Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.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
Sorting 成对条目的水平排序_Sorting_Excel_Vba - Fatal编程技术网

Sorting 成对条目的水平排序

Sorting 成对条目的水平排序,sorting,excel,vba,Sorting,Excel,Vba,我的VBA技能是基本的。如果能帮我把数字排成一行,但移动相应的字符串,我将不胜感激。例如,这些行: ╔═══════╦═════════╦═══════╦═════════╗ ║ Name1 ║ Number1 ║ Name2 ║ Number2 ║ ╠═══════╬═════════╬═══════╬═════════╣ ║ Joe ║ 5 ║ John ║ 10 ║ ╚═══════╩═════════╩═══════╩═════════╝ 应成为: ╔═══

我的VBA技能是基本的。如果能帮我把数字排成一行,但移动相应的字符串,我将不胜感激。例如,这些行:

╔═══════╦═════════╦═══════╦═════════╗
║ Name1 ║ Number1 ║ Name2 ║ Number2 ║
╠═══════╬═════════╬═══════╬═════════╣
║ Joe   ║       5 ║ John  ║      10 ║
╚═══════╩═════════╩═══════╩═════════╝
应成为:

╔═══════╦═════════╦═══════╦═════════╗
║ Name1 ║ Number1 ║ Name2 ║ Number2 ║
╠═══════╬═════════╬═══════╬═════════╣
║ John  ║      10 ║ Joe   ║       5 ║
╚═══════╩═════════╩═══════╩═════════╝
我试图调整的代码是:

Sub hsort()
Dim lLast As Long, lLoop As Long
lLast = Cells(Rows.Count, 1).End(xlUp).Row
For lLoop = 2 To lLast
range(cells(lLoop,4),cells(lLoop,23)).Sort key1:=Cells(lLoop, 5), order1:=xlDescending,key2:=Cells(lLoop, 4), order2:=xlDescending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _False, Orientation:=xlLeftToRight, DataOption1:=xlSortNormal, DataOption2:=xlSortNormal
Next
End Sub

它首先对字符串进行排序,然后对数字进行排序,而不是根据需要将它们移动到一起。

假设Name1位于A1中,如果您在Name1和John之间临时添加一行,并使用=IFISEVENCOLUMN,A3,B3在它的复制,以适应你应该达到的顺序,我认为你想要一个正常的从左到右排序,然后可以删除临时行。如果您愿意,可以将其内置到VBA中。

最后,这是我采用的解决方案,但速度非常慢!是否有人对改进此代码有任何建议?字典对我来说似乎是一个很好的解决方案,但我不知道如何使用它,所以我问你们在这种情况下它是否可以实现

Sub Reorder()

With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
Dim i, c, j As Integer
i = 7

Do
j = 5
Do
Workbooks("Ownership Full v3.xlsx").Activate
Range(Cells(i, j), Cells(i, j + 1)).Copy
Workbooks("Book1.xlsx").Activate
If Range("A2") = blank Then
Range("A2").Select
Else
Range("A1").End(xlDown).Select
Selection.Offset(1, 0).Select
End If
ActiveSheet.Paste
j = j + 2
Workbooks("Ownership Full v3.xlsx").Activate
Loop While (j <= 23)

Workbooks("Book1.xlsx").Activate
    Range("B2:B11").Select
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("B2"), _
        SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
        xlSortTextAsNumbers
    With ActiveWorkbook.Worksheets("Sheet1").Sort
        .SetRange Range("A1:B11")
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
        End With


j = 5
c = 2
Do
Workbooks("Book1.xlsx").Activate
Range(Cells(c, 1), Cells(c, 2)).Cut
Workbooks("Ownership Full v3.xlsx").Activate
Cells(i, j).Select
ActiveSheet.Paste
c = c + 1
j = j + 2
Loop While (c <= 11)

i = i + 1

Loop While (Cells(i, 1) <> blank)

With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = xlCalculationAutomatic
End With

End Sub

使用字典很容易,但正如@pnuts所指出的,它有点高级。我们在这里要做的是调用一个字典,将数据存储在那里,将它们传输到一个数组中,按降序对它们进行冒泡排序,将它们放回字典中,然后打印出来

呼。无论如何,该框架的成功归功于

不管怎样,先编码

'http://www.xl-central.com/sort-a-dictionary-by-item.html
Sub SortDictionaryByItem()

    'Set a reference to Microsoft Scripting Runtime by using
    'Tools > References in the Visual Basic Editor (Alt+F11)

    'Declare the variables
    Dim Dict As Scripting.Dictionary
    Dim Arr() As Variant
    Dim Temp1 As Variant
    Dim Temp2 As Variant
    Dim Txt As String
    Dim i As Long
    Dim j As Long
    Dim LastCol As Long, Iter As Long, Iter2 As Long, Iter3 As Long

    'Create an instance of the Dictionary
    Set Dict = New Dictionary

    'Set the comparison mode to perform a textual comparison
    Dict.CompareMode = TextCompare

    '''''''''''''''''BK201's Mod'''''''''''''''''

    'Get the last column of the row.
    LastCol = Range("A1").End(xlToRight).Column 'Modify accordingly.
    'Add keys and items to the Dictionary
    For Iter = 1 To (LastCol - 1) Step 2
        Dict.Add Cells(1, Iter).Value, Cells(1, Iter + 1).Value
    Next Iter
    '''''''''''''''''BK201's Mod'''''''''''''''''

    'Allocate storage space for the dynamic array
    ReDim Arr(0 To Dict.Count - 1, 0 To 1)

    'Fill the array with the keys and items from the Dictionary
    For i = 0 To Dict.Count - 1
        Arr(i, 0) = Dict.Keys(i)
        Arr(i, 1) = Dict.Items(i)
    Next i

    'Sort the array using the bubble sort method
    For i = LBound(Arr, 1) To UBound(Arr, 1) - 1
        For j = i + 1 To UBound(Arr, 1)
            If Arr(i, 1) < Arr(j, 1) Then
                Temp1 = Arr(j, 0)
                Temp2 = Arr(j, 1)
                Arr(j, 0) = Arr(i, 0)
                Arr(j, 1) = Arr(i, 1)
                Arr(i, 0) = Temp1
                Arr(i, 1) = Temp2
            End If
        Next j
    Next i

    'Clear the Dictionary
    Dict.RemoveAll

    'Add the sorted keys and items from the array back to the Dictionary
    For i = LBound(Arr, 1) To UBound(Arr, 1)
        Dict.Add Key:=Arr(i, 0), Item:=Arr(i, 1)
    Next i

    '''''''''''''''''BK201's Mod'''''''''''''''''
    'Change Cells(2, Iter2) to Cells(1, Iter2) to overwrite.
    KeyIndex = 0
    For Iter2 = 1 To (LastCol - 1) Step 2
        Cells(2, Iter2).Value = Dict.Keys(KeyIndex)
        KeyIndex = KeyIndex + 1
    Next Iter2

    For Iter3 = 2 To LastCol Step 2
        Cells(2, Iter3).Value = Dict.Item(Cells(2, Iter3 - 1).Value)
    Next Iter3
    '''''''''''''''''BK201's Mod'''''''''''''''''

    Set Dict = Nothing

End Sub
截图:

设立:

运行代码后的结果:


相应地修改涉及的范围。让我们知道这是否有帮助。

如果你想得到快速响应而不被否决,那么最好发布你尝试过的内容。你是指我已经尝试过的代码或类似于我的数据截图的内容?理想情况下两者都是。。。因为这将帮助用户解决确切的问题,而不是对整个问题进行编码。使用普通和直接排序是无法做到这一点的。我的建议是重新排列临时工作表中的数据,排序并粘贴回原始位置。使用VBA,您可以将数据存储在字典中,其中名称可以是键,数字可以是项。然后你可以对数据进行排序并粘贴到工作表上。我想我应该更好地解释我需要什么。我在第一行有从A1到X1的标题。前3列不得重新排序;然后我有5000行数据,我必须逐行排序。水平排序不起作用,因为它会对所有选定的单元格重新排序,而我需要的是,如果H列中的值较大,那么G列和H列都会移动到第1个位置,在我的情况下,这是D列,根据您上面的评论,只需将RangeA1.EndxlToRight.column更改为RangeA5.EndxlToRight.column就足够了。我没有费心重写,所以你可以直接看到它。在结尾附近检查注释,以了解覆盖所需的更改:是的,太好了,谢谢!但有一件事我不明白,我想问你。为什么在Dict.Item括号内的最后一次迭代中,您在字典中放置了一个比上一次迭代中的值更高的单元格速率?请注意这一点。基本上,我在这里假设了一件事:名称是唯一的。否则,将它们存储为密钥可能会导致错误。这是因为没有两个键可以具有完全相同的名称。现在,在最后两个迭代的第一个迭代中,我首先映射出已排序的名称。这些名称是键值。在第二次迭代中,为了确保只有相应的伙伴值返回给我们,我们使用名称访问字典的键值对中的值。这有意义吗基本上,Dict.Itemx从键x返回值。因为我们已经绘制了键和名称,剩下的就是得到它们各自的值。因此,我们在单元格上再次迭代,然后引用左侧相邻的单元格,其中包含name键,并使用它提取其伙伴值:这比使用数字索引获取项目要安全得多,无论从哪个角度看,这都会造成无限的悲伤D