使用 VBA 对值列表进行排序(从大到小)
Rank A List Of Values (Largest to Smallest) Using VBA
我有一个 VBA 代码,用于 return 已完成工作的工作人员 ID、工作人员完成的工作总数、工作人员工作了多少天,然后 return 每天的平均作业数。它们没有特别的顺序,所有这些类别在 excel 电子表格中彼此相邻。在这些其他类别旁边的列中,我想编写一个 VBA 代码,根据谁每天的工作量最多,为每一行分配一个值(1 到 10,因为有 10 个工作人员)。
我查看了其他代码和建议,但我只能找到排序。我不想对它们进行排序,因为我可以在 Excel 中轻松地做到这一点,如果我为该特定列对 VBA 中的值进行排序,它们将不会与有关它们的其余信息对齐.关于我如何根据每天平均工作量从最高到最低的人,在相邻列中打印数字 1 到 10 来 "rank" 这些列有什么建议吗?
谢谢大家的帮助!
我从 Accounting Accrual - Invoicing true up Excel 应用程序中删除了这段代码,它是数据 "field".
的多种类型之一
你可以做类似的事情。为了让您更清楚地申请:
wsBuild是一个namedsheet(在developer中,不管worksheet name或position,都可以直接调用)。 "twb" 只是表示它正在这个工作簿中工作,因为我正在合并来自多个工作簿的数据(数据导出,在本例中为 3 个)。
twbNameCol 是在不同函数中找到的供应商名称的列编号
twbJobNumberCol 是在不同函数中找到的销售订单的列编号
twbTot1Col 是在不同函数中找到的销售额的列号
如果您想动态查找 headers,只需以这样的方式选择一个高于您的导入模板的数字,这个可以容纳 2 个总列 headers,一个用于应计和一个发票,你可能不需要做这样的事情,因为我从一个系统导出我知道 header 名称,或者你可以自己制作,差异应计是我要查找的最后一列的位置所以我在那一点打破循环:
twbTot1Col = 0
twbTot2Col = 0
'First let's define the column positions
For j = 1 To 50
If InStr(wsBuild.Cells(1, j), "Totals") > 0 And twbTot1Col = twbTot2Col Then
'It is the first time
twbTot1Col = j
ElseIf InStr(wsBuild.Cells(1, j), "Totals") > 0 And twbTot1Col <> twbTot2Col Then
twbTot2Col = j
ElseIf InStr(wsBuild.Cells(1, j), "JobNumber") > 0 Then
twbJobNumCol = j
ElseIf InStr(wsBuild.Cells(1, j), "New VAP") > 0 Then
twbNewVAPCol = j
ElseIf InStr(wsBuild.Cells(1, j), "New AP") > 0 Then
twbNewAPCol = j
ElseIf InStr(wsBuild.Cells(1, j), "Name") > 0 Then
twbNameCol = j
ElseIf InStr(wsBuild.Cells(1, j), "Diff Accrual") > 0 Then
twbDiffCol = j
j = 100 'Break loop
Else
'Do nothing
End If
Next j
twbLastRow是数据范围的最后一行(数据范围是2到LastRow)
找到是这样的:
twbLastRow = wsBuild.Cells(Rows.Count, 1).End(xlUp).Row
这里是排序代码的例子,在这个1,2,3之前有一些列插入步骤,所以我只复制了排序
With wsBuild
'4) Perform 3 line sort
.Sort.SortFields.Clear
.Sort.SortFields.Add Key:=.Range(.Cells(2, twbNameCol), .Cells(twbLastRow, twbNameCol)), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=.Range(.Cells(2, twbJobNumCol), .Cells(twbLastRow, twbJobNumCol)), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=.Range(.Cells(2, twbTot1Col), .Cells(twbLastRow, twbTot1Col)), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.Sort.SetRange .Range(.Cells(1, 1), .Cells(twbLastRow, twbDiffCol + 2))
.Sort.Header = xlYes
.Sort.MatchCase = False
.Sort.Orientation = xlTopToBottom
.Sort.SortMethod = xlPinYin
.Sort.Apply
End With
如果你看一下这个,你可以"rank"你的数据以任何你喜欢的方式。这种排序是1。供应商 然后 2。工作编号然后3。 accrual amount 然后 funs 开始将发票导入与应计金额相匹配。如果您正确定义排序范围,则不会丢失或错配相邻列中的任何数据。我想我是在游说你使用排序。
如果您提供一些代码,答案实际上可能是您的数据的一种,插入排名列,放入排名,然后将您的数据取消排序,恢复原样。而不是 运行 基于特定属性的 "rank" 函数(更长.....但可行)。干杯,WWC
我有一个 VBA 代码,用于 return 已完成工作的工作人员 ID、工作人员完成的工作总数、工作人员工作了多少天,然后 return 每天的平均作业数。它们没有特别的顺序,所有这些类别在 excel 电子表格中彼此相邻。在这些其他类别旁边的列中,我想编写一个 VBA 代码,根据谁每天的工作量最多,为每一行分配一个值(1 到 10,因为有 10 个工作人员)。
我查看了其他代码和建议,但我只能找到排序。我不想对它们进行排序,因为我可以在 Excel 中轻松地做到这一点,如果我为该特定列对 VBA 中的值进行排序,它们将不会与有关它们的其余信息对齐.关于我如何根据每天平均工作量从最高到最低的人,在相邻列中打印数字 1 到 10 来 "rank" 这些列有什么建议吗?
谢谢大家的帮助!
我从 Accounting Accrual - Invoicing true up Excel 应用程序中删除了这段代码,它是数据 "field".
的多种类型之一你可以做类似的事情。为了让您更清楚地申请: wsBuild是一个namedsheet(在developer中,不管worksheet name或position,都可以直接调用)。 "twb" 只是表示它正在这个工作簿中工作,因为我正在合并来自多个工作簿的数据(数据导出,在本例中为 3 个)。
twbNameCol 是在不同函数中找到的供应商名称的列编号
twbJobNumberCol 是在不同函数中找到的销售订单的列编号
twbTot1Col 是在不同函数中找到的销售额的列号
如果您想动态查找 headers,只需以这样的方式选择一个高于您的导入模板的数字,这个可以容纳 2 个总列 headers,一个用于应计和一个发票,你可能不需要做这样的事情,因为我从一个系统导出我知道 header 名称,或者你可以自己制作,差异应计是我要查找的最后一列的位置所以我在那一点打破循环:
twbTot1Col = 0
twbTot2Col = 0
'First let's define the column positions
For j = 1 To 50
If InStr(wsBuild.Cells(1, j), "Totals") > 0 And twbTot1Col = twbTot2Col Then
'It is the first time
twbTot1Col = j
ElseIf InStr(wsBuild.Cells(1, j), "Totals") > 0 And twbTot1Col <> twbTot2Col Then
twbTot2Col = j
ElseIf InStr(wsBuild.Cells(1, j), "JobNumber") > 0 Then
twbJobNumCol = j
ElseIf InStr(wsBuild.Cells(1, j), "New VAP") > 0 Then
twbNewVAPCol = j
ElseIf InStr(wsBuild.Cells(1, j), "New AP") > 0 Then
twbNewAPCol = j
ElseIf InStr(wsBuild.Cells(1, j), "Name") > 0 Then
twbNameCol = j
ElseIf InStr(wsBuild.Cells(1, j), "Diff Accrual") > 0 Then
twbDiffCol = j
j = 100 'Break loop
Else
'Do nothing
End If
Next j
twbLastRow是数据范围的最后一行(数据范围是2到LastRow)
找到是这样的:
twbLastRow = wsBuild.Cells(Rows.Count, 1).End(xlUp).Row
这里是排序代码的例子,在这个1,2,3之前有一些列插入步骤,所以我只复制了排序
With wsBuild
'4) Perform 3 line sort
.Sort.SortFields.Clear
.Sort.SortFields.Add Key:=.Range(.Cells(2, twbNameCol), .Cells(twbLastRow, twbNameCol)), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=.Range(.Cells(2, twbJobNumCol), .Cells(twbLastRow, twbJobNumCol)), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=.Range(.Cells(2, twbTot1Col), .Cells(twbLastRow, twbTot1Col)), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.Sort.SetRange .Range(.Cells(1, 1), .Cells(twbLastRow, twbDiffCol + 2))
.Sort.Header = xlYes
.Sort.MatchCase = False
.Sort.Orientation = xlTopToBottom
.Sort.SortMethod = xlPinYin
.Sort.Apply
End With
如果你看一下这个,你可以"rank"你的数据以任何你喜欢的方式。这种排序是1。供应商 然后 2。工作编号然后3。 accrual amount 然后 funs 开始将发票导入与应计金额相匹配。如果您正确定义排序范围,则不会丢失或错配相邻列中的任何数据。我想我是在游说你使用排序。
如果您提供一些代码,答案实际上可能是您的数据的一种,插入排名列,放入排名,然后将您的数据取消排序,恢复原样。而不是 运行 基于特定属性的 "rank" 函数(更长.....但可行)。干杯,WWC