Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel:以最大距离排列文本单元格_Excel - Fatal编程技术网

Excel:以最大距离排列文本单元格

Excel:以最大距离排列文本单元格,excel,Excel,在我的Excel表格(见下文)中有不同地方的名称:5个阿尔卑斯山,7个大苏尔山,2个不列颠岛 我想自动排序这些地方的方式,一个地方的名称将尽可能远离彼此。例如,2个阿尔卑斯电池之间将有尽可能多的其他位置。可能吗?如果是:如何做 PS:在我的完整列表中有几百个单元格。因此,强烈建议采用自动化解决方案 免责声明:StackOverflow不是一种代码编写服务,您应该真正尝试解决您的问题,而不仅仅是将其放入。然而,它似乎很有趣,让我思考了一分钟多,因此在最后我决定尝试一下 假设您的输入范围看起来像左

在我的Excel表格(见下文)中有不同地方的名称:5个阿尔卑斯山,7个大苏尔山,2个不列颠岛

我想自动排序这些地方的方式,一个地方的名称将尽可能远离彼此。例如,2个阿尔卑斯电池之间将有尽可能多的其他位置。可能吗?如果是:如何做

PS:在我的完整列表中有几百个单元格。因此,强烈建议采用自动化解决方案


免责声明:StackOverflow不是一种代码编写服务,您应该真正尝试解决您的问题,而不仅仅是将其放入。然而,它似乎很有趣,让我思考了一分钟多,因此在最后我决定尝试一下


假设您的输入范围看起来像左边的列,您希望得到右边的列(我完全忽略了2.点):

因此,您需要采取的步骤大致如下:

  • 范围(“A1:A47”)
    中获取值,并将其放入字典中
  • 按值对字典排序
  • 开始在字典中循环,搜索下一个空闲位置(
    GiveMeNextFreePosition()
    )。找到后,将字典的值分配给数组finalRange
  • 循环遍历数组finalRange,并使用offset函数将其中的值写入下一列


免责声明:StackOverflow不是一种代码编写服务,您应该真正尝试解决您的问题,而不仅仅是将其放入。然而,它似乎很有趣,让我思考了一分钟多,因此在最后我决定尝试一下


假设您的输入范围看起来像左边的列,您希望得到右边的列(我完全忽略了2.点):

因此,您需要采取的步骤大致如下:

  • 范围(“A1:A47”)
    中获取值,并将其放入字典中
  • 按值对字典排序
  • 开始在字典中循环,搜索下一个空闲位置(
    GiveMeNextFreePosition()
    )。找到后,将字典的值分配给数组finalRange
  • 循环遍历数组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