|
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
调整算法,从6小时缩减到3小时了
- Private vData As Variant, nRow As Long, dicData As Object, dicCloseLink As Object, dicMinFirst As Object
- Sub CloseLink()
- Dim vSplit As Variant, vSplitLink As Variant
- Dim vLen As Variant, sLink As String, vLink As Variant
- Dim sFirst As String, nBit As Long, sMid As String, bIsSame As Boolean, sStr As String
- Dim nI As Long
-
- [G1] = Now()
- With [A1].CurrentRegion
- vData = .Offset(1).Resize(.Rows.Count - 1).Value
- End With
- Set dicData = CreateObject("Scripting.Dictionary")
- For nRow = 1 To UBound(vData)
- If Trim(vData(nRow, 1)) <> "" And Trim(vData(nRow, 2)) <> "" Then
- If Not dicData.Exists(Trim(vData(nRow, 1))) Then Set dicData(Trim(vData(nRow, 1))) = CreateObject("Scripting.Dictionary")
- dicData(Trim(vData(nRow, 1)))(Trim(vData(nRow, 2))) = ""
- End If
- Next
- ReDim vData(0)
- nRow = 0
-
- Set dicCloseLink = CreateObject("Scripting.Dictionary")
- Set dicMinFirst = CreateObject("Scripting.Dictionary")
- GetLink dicData
-
- [D:E].ClearContents
- If nRow > 0 Then
- ReDim vSplit(1 To UBound(vData), 1 To 1)
- For nRow = 1 To UBound(vSplit)
- If Trim(vData(nRow)) <> "" Then vSplit(nRow, 1) = vData(nRow) & "∮"
- Next
- [D1].Resize(UBound(vSplit)) = vSplit
- End If
- [H1] = Now()
- End Sub
- Private Function GetLink(ByVal oDic As Object, Optional ByVal dicLink As Object)
- Dim vKey As Variant, dicTmp As Object, vTmp As Variant, sMin As String, sMinFirst As String, nI As Long
-
- If dicLink Is Nothing Then Set dicLink = CreateObject("Scripting.Dictionary")
- For Each vKey In oDic.Keys
- If Not dicLink.Exists(vKey) Then
- If dicData.Exists(vKey) Then
- Set dicTmp = CreateObject("Scripting.Dictionary")
- For Each vTmp In dicLink.Keys
- dicTmp(vTmp) = dicTmp.Count
- Next
- dicTmp(vKey) = dicTmp.Count
- GetLink dicData(vKey), dicTmp
- End If
- ElseIf dicLink.Count > 2 Then
- If vKey = dicLink.Keys()(0) Then
- sMinFirst = FindMin(dicLink.Keys())
- If dicLink.Keys()(0) = sMinFirst Then
- sMin = Join(dicLink.Keys(), "→")
- Else
- Set dicTmp = CreateObject("Scripting.Dictionary")
- For nI = dicLink(sMinFirst) To dicLink.Count - 1
- dicTmp(dicLink.Keys()(nI)) = dicTmp.Count
- Next
- For Each vTmp In dicLink.Keys
- If vTmp = sMinFirst Then Exit For
- dicTmp(vTmp) = dicTmp.Count
- Next
- sMin = Join(dicTmp.Keys(), "→")
- End If
- If Not dicMinFirst.Exists(sMin) Then
- dicMinFirst(sMin) = 0
- nRow = nRow + 1
- ReDim Preserve vData(1 To nRow)
- vData(nRow) = Join(dicLink.Keys(), "→")
- End If
- End If
- End If
- Next
- End Function
- Private Function FindMin(ByVal vMin As Variant) As String
- Dim nI As Double, nJ As Double, vTmp As Variant
-
- nJ = LBound(vMin)
- For nI = LBound(vMin) To UBound(vMin) - 1
- If vMin(nI) <= vMin(nI + 1) Then
- If nI > nJ Then
- nJ = nI
- Else
- nI = nJ
- End If
- Else
- vTmp = vMin(nI)
- vMin(nI) = vMin(nI + 1)
- vMin(nI + 1) = vTmp
- If nI <> LBound(vMin) Then nI = nI - 2
- End If
- Next nI
- FindMin = vMin(LBound(vMin))
- End Function
复制代码 |
|