Excel:以最大距离排列文本单元格
在我的Excel表格(见下文)中有不同地方的名称:5个阿尔卑斯山,7个大苏尔山,2个不列颠岛 我想自动排序这些地方的方式,一个地方的名称将尽可能远离彼此。例如,2个阿尔卑斯电池之间将有尽可能多的其他位置。可能吗?如果是:如何做 PS:在我的完整列表中有几百个单元格。因此,强烈建议采用自动化解决方案Excel:以最大距离排列文本单元格,excel,Excel,在我的Excel表格(见下文)中有不同地方的名称:5个阿尔卑斯山,7个大苏尔山,2个不列颠岛 我想自动排序这些地方的方式,一个地方的名称将尽可能远离彼此。例如,2个阿尔卑斯电池之间将有尽可能多的其他位置。可能吗?如果是:如何做 PS:在我的完整列表中有几百个单元格。因此,强烈建议采用自动化解决方案 免责声明:StackOverflow不是一种代码编写服务,您应该真正尝试解决您的问题,而不仅仅是将其放入。然而,它似乎很有趣,让我思考了一分钟多,因此在最后我决定尝试一下 假设您的输入范围看起来像左
免责声明:StackOverflow不是一种代码编写服务,您应该真正尝试解决您的问题,而不仅仅是将其放入。然而,它似乎很有趣,让我思考了一分钟多,因此在最后我决定尝试一下
假设您的输入范围看起来像左边的列,您希望得到右边的列(我完全忽略了2.点): 因此,您需要采取的步骤大致如下:
- 从
中获取值,并将其放入字典中李>范围(“A1:A47”)
- 按值对字典排序李>
- 开始在字典中循环,搜索下一个空闲位置(
)。找到后,将字典的值分配给数组finalRange李>GiveMeNextFreePosition()
- 循环遍历数组finalRange,并使用offset函数将其中的值写入下一列李>
免责声明:StackOverflow不是一种代码编写服务,您应该真正尝试解决您的问题,而不仅仅是将其放入。然而,它似乎很有趣,让我思考了一分钟多,因此在最后我决定尝试一下
假设您的输入范围看起来像左边的列,您希望得到右边的列(我完全忽略了2.点): 因此,您需要采取的步骤大致如下:
- 从
中获取值,并将其放入字典中李>范围(“A1:A47”)
- 按值对字典排序李>
- 开始在字典中循环,搜索下一个空闲位置(
)。找到后,将字典的值分配给数组finalRange李>GiveMeNextFreePosition()
- 循环遍历数组finalRange,并使用offset函数将其中的值写入下一列李>
我很失望这个问题得到了回答,但我赞扬你的努力!你付出的努力比OP多了100倍@CallumDA-我完全明白你的意思。你从我这里得到+1,因为我喜欢看
ArrayList
:D@CallumDA-这正是我在帖子中没有提到的内容:我认为它最初是谁的代码并不重要。这是很好的代码!我很失望这个问题得到了回答,但我赞扬你的努力!你付出的努力比OP多了100倍@CallumDA-我完全明白你的意思。你从我这里得到+1,因为我喜欢看ArrayList
:D@CallumDA-这正是我在帖子中没有提到的内容:我认为它最初是谁的代码并不重要。这是很好的代码!谢谢你的帮助@CallumDA。我把问题改成了一个问题。现在这应该是一个可以问的问题了,不是吗?谢谢你的帮助@CallumDA。我把问题改成了一个问题。现在这应该是一个可以问的问题,不是吗?
Option Explicit
Public Sub TestMe()
'with a reference for MicrosoftScriptingRuntime
Dim dict As New Scripting.Dictionary
Dim myCell As Range
Dim initialRange As Range
Set initialRange = Range("A1:A47")
For Each myCell In initialRange
If dict.Exists(myCell.value) Then
dict(myCell.value) = dict(myCell.value) + 1
Else
dict.Add myCell.value, 1
End If
Next myCell
'sort the dictionary
Set dict = SortDictionaryByValue(dict, xlDescending)
Dim finalRange As Variant
ReDim finalRange(initialRange.Count)
Dim myKey As Variant
For Each myKey In dict.Keys
Dim cnt As Long
Dim placesLeft As Long
While dict(myKey) > 0
dict(myKey) = dict(myKey) - 1
cnt = GiveMeNextFreePosition(finalRange, myKey)
finalRange(cnt) = myKey
Wend
Next myKey
Dim rowCounter As Long
rowCounter = initialRange.Cells(1, 1).Row - 1
For Each myCell In initialRange.Offset(0, 1)
myCell = finalRange(rowCounter)
rowCounter = rowCounter + 1
Next myCell
End Sub
Public Function GiveMeNextFreePosition(ByRef arr As Variant, _
ByVal myInput As String) As Long
Dim cnt As Long: cnt = -1
Dim reserve As Long
For cnt = LBound(arr) To UBound(arr)
If arr(cnt) = vbNullString Then
reserve = cnt
If cnt <> LBound(arr) Then
If arr(cnt - 1) <> myInput Then
GiveMeNextFreePosition = cnt
Exit Function
End If
Else
GiveMeNextFreePosition = 0
Exit Function
End If
End If
Next cnt
GiveMeNextFreePosition = reserve
End Function
Public Function SortDictionaryByValue(dict As Object _
, Optional sortorder As XlSortOrder = xlAscending) As Object
On Error GoTo eh
Dim arrayList As Object
Set arrayList = CreateObject("System.Collections.ArrayList")
Dim dictTemp As Object
Set dictTemp = CreateObject("Scripting.Dictionary")
' Put values in ArrayList and sort
' Store values in tempDict with their keys as a collection
Dim key As Variant, value As Variant, coll As Collection
For Each key In dict
value = dict(key)
' if the value doesn't exist in dict then add
If dictTemp.Exists(value) = False Then
' create collection to hold keys
' - needed for duplicate values
Set coll = New Collection
dictTemp.Add value, coll
' Add the value
arrayList.Add value
End If
' Add the current key to the collection
dictTemp(value).Add key
Next key
' Sort the value
arrayList.Sort
' Reverse if descending
If sortorder = xlDescending Then
arrayList.Reverse
End If
dict.RemoveAll
' Read through the ArrayList and add the values and corresponding
' keys from the dictTemp
Dim item As Variant
For Each value In arrayList
Set coll = dictTemp(value)
For Each item In coll
dict.Add item, value
Next item
Next value
Set arrayList = Nothing
' Return the new dictionary
Set SortDictionaryByValue = dict
Done:
Exit Function
eh:
If Err.Number = 450 Then
Err.Raise vbObjectError + 100, "SortDictionaryByValue" _
, "Cannot sort the dictionary if the value is an object"
End If
End Function