Excel公式/VBA以对表格进行排序

huangapple go评论74阅读模式
英文:

Excel formula/VBA to sort table

问题

如何对表格进行排序?我有一个数据集(列 A - G),我想按照上述顺序仅显示列 A、C、E、B。是否有可以用来自动化的 Excel 公式 / VBA 公式?

英文:

How to sort a table? I have a dataset (column A - G) that I would like to sort to show only columns A, C, E, B in the above order. Is there an excel formula / VBA formula that I can look into to automate?

答案1

得分: 1

选择列

Excel公式/VBA以对表格进行排序

Excel公式

Microsoft 365 2022

=CHOOSECOLS(A1:G11,1,3,5,2)

或者使用包含行分隔符的数组

=CHOOSECOLS(A1:G11,{1;3;5;2})

或者使用正确的列分隔符的数组
或者前两者的组合。

Microsoft 365 2021

=LET(d,A1:G11,c,{1,3,5,2},
    r,SEQUENCE(ROWS(d)),
INDEX(d,r,c))
  • 根据您的小数分隔符,数组中的列分隔符(数组{1,3,5,2}中的逗号)可能不同。
    到目前为止,我遇到了{1.3.5.2}{1\3\5\2}{1@3@5@2}

  • 为了使其适用于任何区域设置,您可以使用TRANSPOSE(还没有TOROW)与行分隔符:

=LET(d,A1:G11,rc,{1;3;5;2},
    r,SEQUENCE(ROWS(d)),c,TRANSPOSE(rc),
INDEX(d,r,c))

旧版本

=INDEX(A1:G11,ROW(A1:G11)-ROW(A1)+1,{1,3,5,2}) 

如果您的数据从第1行开始,可以简化为:

=INDEX(A1:G11,ROW(A1:G11),{1,3,5,2})
  • 2021版本一样,您可以通过使用TRANSPOSE({1;3;5;2})来使两者都适用于任何区域设置。

VBA

包括公式和格式在内复制

Sub CopyColumns()

    Dim Cols(): Cols = Array(1, 3, 5, 2)

    Dim wb As Workbook: Set wb = ThisWorkbook ' 包含此代码的工作簿
    Dim ws As Worksheet: Set ws = wb.Sheets("Sheet1")
    
    Dim srg As Range: Set srg = ws.Range("A1").CurrentRegion
    
    Dim dfCell As Range: Set dfCell = ws.Range("I1")
    
    Dim Col
    
    For Each Col In Cols
        Debug.Print "复制" & Chr(34) & srg.Columns(Col).Address(0, 0) _
            & Chr(34) & "到" & Chr(34) & dfCell.Address(0, 0) & Chr(34) & "..."
        srg.Columns(Col).Copy dfCell
        Set dfCell = dfCell.Offset(, 1)
    Next Col
 
    MsgBox "列已复制。", vbInformation

End Sub

仅复制值(使用函数)

函数

Function ChooseColumns( _
    ByVal SourceRange As Range, _
    ByVal ChosenColumns As Variant) _
As Variant
    
    Dim rCount As Long: rCount = SourceRange.Rows.Count
    Dim scCount As Long: scCount = SourceRange.Columns.Count
    
    Dim sData()
    
    If rCount * scCount = 1 Then
        ReDim sData(1 To 1, 1 To 1): sData(1, 1) = SourceRange.Value
    Else
        sData = SourceRange.Value
    End If
        
    Dim dcCount As Long:
    dcCount = UBound(ChosenColumns) - LBound(ChosenColumns) + 1
    
    Dim dData(): ReDim dData(1 To rCount, 1 To dcCount)
        
    Dim sCol, r As Long, dc As Long
    
    For Each sCol In ChosenColumns
        dc = dc + 1
        For r = 1 To rCount
            dData(r, dc) = sData(r, sCol)
        Next r
    Next sCol

    ChooseColumns = dData

End Function

子程序(使用函数)

Sub CopyColumnsUsingFunction()

    Dim Cols(): Cols = Array(1, 3, 5, 2)

    Dim wb As Workbook: Set wb = ThisWorkbook ' 包含此代码的工作簿
    Dim ws As Worksheet: Set ws = wb.Sheets("Sheet1")
    
    Dim srg As Range: Set srg = ws.Range("A1").CurrentRegion
    
    Dim Data(): Data = ChooseColumns(srg, Cols)
    
    Dim dfCell As Range: Set dfCell = ws.Range("I1")
    
    dfCell.Resize(UBound(Data, 1), UBound(Data, 2)).Value = Data
    
    MsgBox "列已复制。", vbInformation

End Sub

列表分隔符

Sub ShowMySeparators()
    With Application
        Debug.Print "备用: " & .International(xlAlternateArraySeparator)
        Debug.Print "列: " & .International(xlColumnSeparator)
        Debug.Print "小数: " & .International(xlDecimalSeparator)
        Debug.Print "列表: " & .International(xlListSeparator)
        Debug.Print "行: " & .International(xlRowSeparator)
        Debug.Print "千位分隔符: " & .International(xlThousandsSeparator)
    End With
End Sub

我的系统上的结果

备用: @
列: ,
小数: .
列表: ;
行: ;
千位分隔符: ,
英文:

Choose Columns

Excel公式/VBA以对表格进行排序

Excel Formula

Microsoft 365 2022

=CHOOSECOLS(A1:G11,1,3,5,2)

or by using an array with row separators

=CHOOSECOLS(A1:G11,{1;3;5;2})

or using the array with the correct column separators
or a combination of the previous two.

Microsoft 365 2021

=LET(d,A1:G11,c,{1,3,5,2},
    r,SEQUENCE(ROWS(d)),
INDEX(d,r,c))
  • Depending on your decimal separator, the array column separator (the comma(s) in the array {1,3,5,2}) may be different.
    So far, I have encountered {1.3.5.2}, {1\3\5\2}, or {1@3@5@2}.

  • To make it work on any locale, you could use TRANSPOSE (there is no TOROW yet) with row separators:

=LET(d,A1:G11,rc,{1;3;5;2},
    r,SEQUENCE(ROWS(d)),c,TRANSPOSE(rc),
INDEX(d,r,c))

Older Versions

=INDEX(A1:G11,ROW(A1:G11)-ROW(A1)+1,{1,3,5,2}) 

If your data starts in row 1, you can simplify with:

=INDEX(A1:G11,ROW(A1:G11),{1,3,5,2})
  • The same as in 2021, you can make both work for any locale by using TRANSPOSE({1;3;5;2}).

VBA

Copy Including Formulas and Formatting

Sub CopyColumns()

    Dim Cols(): Cols = Array(1, 3, 5, 2)

    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    Dim ws As Worksheet: Set ws = wb.Sheets("Sheet1")
    
    Dim srg As Range: Set srg = ws.Range("A1").CurrentRegion
    
    Dim dfCell As Range: Set dfCell = ws.Range("I1")
    
    Dim Col
    
    For Each Col In Cols
        Debug.Print "Copying """ & srg.Columns(Col).Address(0, 0) _
            & """ to """ & dfCell.Address(0, 0) & """..."
        srg.Columns(Col).Copy dfCell
        Set dfCell = dfCell.Offset(, 1)
    Next Col
 
    MsgBox "Columns copied.", vbInformation

End Sub

Copy Values Only (Using a Function)

The Function

Function ChooseColumns( _
    ByVal SourceRange As Range, _
    ByVal ChosenColumns As Variant) _
As Variant
    
    Dim rCount As Long: rCount = SourceRange.Rows.Count
    Dim scCount As Long: scCount = SourceRange.Columns.Count
    
    Dim sData()
    
    If rCount * scCount = 1 Then
        ReDim sData(1 To 1, 1 To 1): sData(1, 1) = SourceRange.Value
    Else
        sData = SourceRange.Value
    End If
        
    Dim dcCount As Long:
    dcCount = UBound(ChosenColumns) - LBound(ChosenColumns) + 1
    
    Dim dData(): ReDim dData(1 To rCount, 1 To dcCount)
        
    Dim sCol, r As Long, dc As Long
    
    For Each sCol In ChosenColumns
        dc = dc + 1
        For r = 1 To rCount
            dData(r, dc) = sData(r, sCol)
        Next r
    Next sCol

    ChooseColumns = dData

End Function

The Sub (Using the Function)

Sub CopyColumnsUsingFunction()

    Dim Cols(): Cols = Array(1, 3, 5, 2)

    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    Dim ws As Worksheet: Set ws = wb.Sheets("Sheet1")
    
    Dim srg As Range: Set srg = ws.Range("A1").CurrentRegion
    
    Dim Data(): Data = ChooseColumns(srg, Cols)
    
    Dim dfCell As Range: Set dfCell = ws.Range("I1")
    
    dfCell.Resize(UBound(Data, 1), UBound(Data, 2)).Value = Data
    
    MsgBox "Columns copied.", vbInformation

End Sub

List Separators

Sub ShowMySeparators()
    With Application
        Debug.Print "Alternate: " & .International(xlAlternateArraySeparator)
        Debug.Print "Column: " & .International(xlColumnSeparator)
        Debug.Print "Decimal: " & .International(xlDecimalSeparator)
        Debug.Print "List: " & .International(xlListSeparator)
        Debug.Print "Row: " & .International(xlRowSeparator)
        Debug.Print "Thousands: " & .International(xlThousandsSeparator)
    End With
End Sub

Results on My System

Alternate: @
Column: ,
Decimal: .
List: ;
Row: ;
Thousands: ,

huangapple
  • 本文由 发表于 2023年6月16日 07:14:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76486043.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定