⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcommon.bas

📁 用vb写的一个小程序。希望喜欢。 LHBSEAMAN·163。COM
💻 BAS
字号:
Attribute VB_Name = "mCommon"
Option Compare Binary
Option Explicit

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal numbytes As Long)

Public Const APPTITLE   As String = "WebCoder"
Public Const FLD        As String = "fld_"
Public Const TBL        As String = "tbl_"
Public Const QRY        As String = "qry_"
Public Const IDX        As String = "idx"

Public Const strUSERDB  As String = "\convert.mdb"
Public Const lngDBVER   As Long = dbVersion30

Public ActiveDB         As DAO.Database
Public ActiveWS         As DAO.Workspace

Public Function fcnGetDelimitedRecord(strLine As String, Optional strTextQualifier As String = """", Optional strDelimiter As String = ",") As Variant
  '***  function to get a line of a delimited text file into an array of strings
  '***  returns field # in array item 0
  '***  unquotes quoted fields and works well on long lines of text

  Dim lngPos           As Long
  Dim lngItemFound     As Long
  Dim lngLen           As Long
  Dim lngCounter       As Long
  Dim blnInQuotedField As Boolean
  Dim arrLineChars()   As Byte
  Dim bytQualifier     As Byte
  Dim bytDelimiter     As Byte
  Dim lngItemStart     As Long
  Dim lngItemEnd       As Long
  Dim arrItems()       As String

  '***  initialize array
  ReDim arrItems(0)

  If LenB(strLine) <> 0 Then

    bytQualifier = Asc(strTextQualifier)
    bytDelimiter = Asc(strDelimiter)
    arrLineChars = StrConv(strLine & strDelimiter, vbFromUnicode)
    lngLen = UBound(arrLineChars, 1)
    lngItemEnd = -1

    '***  find the right item
    For lngPos = 0 To lngLen

      Select Case arrLineChars(lngPos)

        Case 10
          If Not blnInQuotedField Then
            lngItemFound = lngItemFound + 1
            lngItemStart = lngItemEnd + 1
            lngItemEnd = lngPos
            Mid$(strLine, lngPos, 1) = Chr(32&)
          End If

        Case 13
          If Not blnInQuotedField Then
            Mid$(strLine, lngPos, 1) = Chr(32&)
          End If

        Case bytDelimiter
          If Not blnInQuotedField Then
            lngItemFound = lngItemFound + 1
            lngItemStart = lngItemEnd + 1
            lngItemEnd = lngPos
          End If

        Case bytQualifier
          blnInQuotedField = Not blnInQuotedField

      End Select

      If lngItemFound > UBound(arrItems, 1) Then
        ReDim Preserve arrItems(0 To lngItemFound) As String
        arrItems(lngItemFound) = Trim$(Mid$(strLine, lngItemStart + 1, lngItemEnd - lngItemStart))
      End If
    Next

    '***  unquote if quoted - double delimit to single
    For lngCounter = 1 To UBound(arrItems, 1)

      If Len(arrItems(lngCounter)) > 1 Then
        '***  item is long enough to be delimited

        If Asc(arrItems(lngCounter)) = bytQualifier And Asc(Right$(arrItems(lngCounter), 1)) = bytQualifier Then
          '***  remove the surrounding quotes
          arrItems(lngCounter) = Mid$(arrItems(lngCounter), 2, Len(arrItems(lngCounter)) - 2)
          '***  replace double quotes
          arrItems(lngCounter) = fcnReplaceB(arrItems(lngCounter), Chr$(bytQualifier) & Chr$(bytQualifier), Chr$(bytQualifier))
        End If

      End If

    Next

  End If

  arrItems(0) = Str$(lngItemFound)
  fcnGetDelimitedRecord = arrItems()
End Function

Function fcnReplaceB(ByRef strReplace As String, ByRef strOld As String, ByRef strNew As String) As String
  '***  use the appropriate replace function VB6 Replace is 60% slower
  If Len(strReplace) > 4000 Then

    '***  do not use the binary replace if there are no hits
    If InStr(1, strReplace, strOld, vbBinaryCompare) > 0 Then
      fcnReplaceB = fcnReplaceB1(strReplace, strOld, strNew)

    Else
      fcnReplaceB = strReplace
    End If

  Else

    fcnReplaceB = fcnReplaceB2(strReplace, strOld, strNew)

  End If

End Function

Function fcnReplaceB1(ByRef strReplace As String, ByRef strOld As String, ByRef strNew As String, Optional lngCount As Long) As String
  Dim arrReplace()     As Byte
  Dim arrOld()         As Byte
  Dim arrNew()         As Byte
  Dim arrReturn()      As Byte

  arrReplace() = StrConv(strReplace, vbFromUnicode)
  arrOld() = StrConv(strOld, vbFromUnicode)
  arrNew() = StrConv(strNew, vbFromUnicode)

  lngCount = fcnReplaceByteArray(arrReplace(), arrOld(), arrNew(), arrReturn())

  fcnReplaceB1 = StrConv(arrReturn(), vbUnicode)
End Function

Function fcnReplaceB2(ByRef strReplace As String, ByRef strOld As String, ByRef strNew As String) As String
  Dim lngPos           As Long
  lngPos = InStr(1, strReplace, strOld, vbBinaryCompare)
  If lngPos <> 0 Then
    fcnReplaceB2 = Left$(strReplace, lngPos - 1) & strNew & fcnReplaceB2(Mid$(strReplace, lngPos + Len(strOld)), strOld, strNew)
  Else
    fcnReplaceB2 = strReplace
  End If
End Function

Function fcnReplaceByteArray(ByRef arrSearch() As Byte, ByRef arrOld() As Byte, ByRef arrNew() As Byte, ByRef arrReplaced() As Byte) As Long
  '***  fast replace without string concatination
  '***  uses rtlcopymem function
  '***  !TODO: memory reservation is exorbitant when the new string is longer than the old one
  '***  should be easy to fix

  Dim lngPos           As Long
  Dim lngBaseOut       As Long
  Dim lngCount         As Long
  Dim lngReplaceCount  As Long
  Dim lngLenOld        As Long
  Dim lngLenNew        As Long
  Dim lngLenInput      As Long
  Dim lngBuffer        As Long
  Dim lngLenPart       As Long
  Dim lngMaxBuffer     As Long
  Dim lngNoBlocks      As Long
  Dim lngExtra         As Long
  Dim lngMain          As Long
  Dim lngLOF           As Long
  Dim lngBlockSize     As Long
  Dim lngPosition      As Long
  Dim lngNoHits        As Long
  Dim arrReplace()     As Byte
  Dim arrLeftOver()    As Byte
  Dim lngOver          As Long

  '***  important performance setting to avoid slow InStr() on long strings
  lngBlockSize = 1200

  lngLOF = UBound(arrSearch) + 1
  lngNoBlocks = lngLOF \ lngBlockSize
  lngExtra = lngLOF Mod lngBlockSize
  lngMain = (lngNoBlocks) * lngBlockSize
  lngBaseOut = -1
  ReDim arrLeftOver(-1 To -1)

  lngLenOld = UBound(arrOld) + 1
  lngLenNew = UBound(arrNew) + 1

  'Debug.Print "[" & lngLOF & "]";

  If lngLenOld = 0 Or lngLOF = 0 Then

    arrReplaced = arrSearch
    fcnReplaceByteArray = 0

  Else

    '***  block loop
    For lngCount = 0 To lngMain Step lngBlockSize

      '***  fill the replace string
      If lngCount < lngMain Then
        '***  all blocks use this copy
        ReDim arrReplace(lngBlockSize - 1 + UBound(arrLeftOver) + 1)
        CopyMemory arrReplace(UBound(arrLeftOver) + 1), arrSearch(lngCount), lngBlockSize
        If lngOver > 0 Then
          CopyMemory arrReplace(0), arrLeftOver(0), UBound(arrLeftOver) + 1
        End If
      ElseIf lngExtra > 0 Then
        '***  only the last block uses this copy
        ReDim arrReplace(lngExtra - 1 + UBound(arrLeftOver) + 1)
        CopyMemory arrReplace(UBound(arrLeftOver) + 1), arrSearch(lngCount), lngExtra
        If lngOver > 0 Then
          CopyMemory arrReplace(0), arrLeftOver(0), UBound(arrLeftOver) + 1
        End If
      ElseIf lngExtra = 0 Then
        '*** we'r finished - exit the for-next
        Exit For
      End If

      lngLenInput = UBound(arrReplace) + 1

      If lngLenNew = 0 Then
        ReDim arrNew(0)
      End If

      '***  memory reservation: create a buffer for the output
      If (lngLenNew - lngLenOld) <= 0 Then
        '***  the output will be smaller of equal in length
        lngBuffer = UBound(arrReplace)
      Else
        '***  the output may be longer than the input
        lngMaxBuffer = UBound(arrReplace) + (lngLenInput \ lngLenOld) * (lngLenNew - lngLenOld)
        lngBuffer = lngMaxBuffer
      End If

      ReDim Preserve arrReplaced(lngBaseOut + lngBuffer + 1)
      lngPosition = 1

      '***  replace loop
      Do

        lngPos = InStrB(lngPosition, arrReplace, arrOld, vbBinaryCompare)
        lngPos = lngPos - 1

        If lngPos < 0 Then
          '***  nothing found: add the rightmost part

          '***  lngNoHits: number of bytes without a hit in this block
          lngNoHits = lngLenInput - lngPosition + 1
          If lngNoHits < lngLenOld Then
            '***  do not re-check bytes that were replaced already
            arrLeftOver() = RightB(arrReplace, lngNoHits)
            lngOver = lngNoHits
          Else
            '***  re-check the last bytes. eg. searching for 'secret' --> the last bytes could be 'secre'
            '***  to check if the next block starts with 't', always copy lngLenOld - 1 bytes
            arrLeftOver() = RightB(arrReplace, lngLenOld - 1)
            lngOver = lngLenOld - 1
          End If

          If lngNoHits > 0 Then
            CopyMemory arrReplaced(lngBaseOut + 1), arrReplace(lngPosition - 1), lngNoHits - lngOver
          End If

          lngBaseOut = lngBaseOut + lngNoHits - lngOver
        Else
          '***  we've found it

          '***  set the string-part length
          lngLenPart = lngPos - lngPosition + 1

          '***  add the left part
          CopyMemory arrReplaced(lngBaseOut + 1), arrReplace(lngPosition - 1), lngLenPart

          '***  copy the new part if lngLenNew > 0
          CopyMemory arrReplaced(lngBaseOut + 1 + lngLenPart), arrNew(0), lngLenNew

          '***  set the new lngBaseOut value
          lngBaseOut = lngBaseOut + lngLenPart + lngLenNew

          '***  set the new position
          lngPosition = lngPos + 1 + lngLenOld

          lngReplaceCount = lngReplaceCount + 1
        End If

      Loop Until lngPos < 0
      '***  replace loop

    Next lngCount
    '***  block loop

    '***  clear extra bytes in the buffer and add leftover bytes
    ReDim Preserve arrReplaced(lngBaseOut + lngOver)
    If lngOver > 0 Then
      CopyMemory arrReplaced(lngBaseOut + 1), arrLeftOver(0), lngOver
    End If

    fcnReplaceByteArray = lngReplaceCount

  End If

End Function

Function fcnGetFile(strFileName As String) As String
  '***  returns a unicode string representation of the file
  Dim lngFile          As Long
  Dim strFile          As String

  lngFile = FreeFile
  Open strFileName For Binary Access Read As lngFile
  strFile = Space$(LOF(lngFile))
  Get #lngFile, 1, strFile
  Close lngFile
  fcnGetFile = strFile
End Function

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -