Excel 的排序是否与其默认的美国字符集不同?

wii*_*ame 5 excel sap customization vba character-set

我的问题基本上与THIS ONE相反(它有一个基于数据库的解决方案,我不能在这里使用)。

我使用 SAP,它以这种方式对字符进行排序:

0-9, AZ, _

但我正在将数据下载到 Excel 并根据正确的 SAP 字符集排序顺序操作范围。

如何强制 Excel 以与 SAP 相同的方式排序,下划线排在最后。

在 Excel 的排序功能中尝试自定义单个字符的排序列表后,Excel 仍然/总是这样排序:

_, 0-9, AZ

有没有办法让 Excel 像 SAP 一样排序?如果需要,我可以执行 Excel 宏。

或者,如果有人知道如何让本机 SAP 表像 SAP 界面中的 Excel 一样排序,那也可以解决这个问题。

San*_*ssi 2

以下解决方案的原理是插入一个新列,其中的单元格具有一个公式,该公式计算要排序的列的每个单元格的“可排序代码”。

\n\n

如果您对此新列进行排序,则行将按 ASCII 顺序 ( 0-9, A-Z, _) 排序。

\n\n

它应该能够处理任意数量的行。在我的笔记本电脑上,计算 130.000 行的单元格需要 1 分钟。有两种 VBA 函数,一种用于 ASCII,一种用于 EBCDIC。定义其他字符集非常容易。

\n\n

脚步:

\n\n
    \n
  • 在 Excel 工作簿中创建一个模块并放置以下代码。
  • \n
  • 关闭VB编辑器,否则运行速度会变慢
  • \n
  • 在要排序的工作表中,为要排序的每一列插入一列,例如,假设要对 A 列进行排序,创建一个新的 B 列,在单元格中插入B1公式=SortableCodeASCII(A1)并对 B 列的所有单元格执行相同的操作(直到 A 列的最后一行)。
  • \n
  • 确保公式的计算已经结束(我的笔记本上130.000行需要1分钟),否则如果排序,顺序会不正确,因为公式还没有计算。您可以在 Excel 窗口底部的状态栏上看到进度指示器(百分比)。如果您没有看到它,请按Ctrl+ Alt+ F9
  • \n
  • 对 B 列进行排序。A 列中的值应根据 ASCII 顺序进行排序 ( 0-9, A-Z, _)
  • \n
\n\n

祝你好运!

\n\n
Option Compare Text \'to make true "a" = "A", "_" < "0", etc.\nOption Base 0 \'to start arrays at index 0 (LBound(array) = 0)\nDim SortableCharactersASCII() As String\nDim SortableCharactersEBCDIC() As String\nDim SortableCharactersTEST() As String\n\nSub ResetSortableCode()\n    \'Run this subroutine if you change anything in the code of this module\n    \'to regenerate the arrays SortableCharacters*\n    Erase SortableCharactersASCII\n    Erase SortableCharactersEBCDIC\n    Erase SortableCharactersTEST\n    Call SortableCodeASCII("")\n    Call SortableCodeEBCDIC("")\n    Call SortableCodeTEST("")\nEnd Sub\n\nFunction SortableCodeASCII(text As String)\n    If (Not Not SortableCharactersASCII) = 0 Then\n        SortableCharactersASCII = getSortableCharacters( _\n            orderedCharacters:=" !""#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}" & ChrW(126) & ChrW(127))\n    End If\n    SortableCodeASCII = getSortableCode(text, SortableCharactersASCII)\nEnd Function\n\nFunction SortableCodeEBCDIC(text As String)\n    If (Not Not SortableCharactersEBCDIC) = 0 Then\n        SortableCharactersEBCDIC = getSortableCharacters( _\n            orderedCharacters:=" \xc2\xa2.<(+|&!$*);-/\xc2\xa6,%_>?`:#@\'=""abcdefghi\xc2\xb1jklmnopqr~stuvwxyz^[]{ABCDEFGHI}JKLMNOPQR\\STUVWXYZ0123456789")\n    End If\n    SortableCodeEBCDIC = getSortableCode(text, SortableCharactersEBCDIC)\nEnd Function\n\nFunction SortableCodeTEST(text As String)\n    If (Not Not SortableCharactersTEST) = 0 Then\n        SortableCharactersTEST = getSortableCharacters( _\n            orderedCharacters:="ABCDEF 0123456789_")\n    End If\n    SortableCodeTEST = getSortableCode(text, SortableCharactersTEST)\nEnd Function\n\nFunction getSortableCharacters(orderedCharacters As String) As String()\n\n    \'Each character X is assigned another character Y so that sort by character Y will\n    \'sort character X in the desired order.\n\n    maxAscW = 0\n    For i = 1 To Len(orderedCharacters)\n         If AscW(Mid(orderedCharacters, i, 1)) > maxAscW Then\n            maxAscW = AscW(Mid(orderedCharacters, i, 1))\n         End If\n    Next\n\n    Dim aTemp() As String\n    ReDim aTemp(maxAscW)\n    j = 0\n    For i = 1 To Len(orderedCharacters)\n        \'Was a character with same "sort weight" previously processed ("a" = "A")\n        For i2 = 1 To i - 1\n            If AscW(Mid(orderedCharacters, i, 1)) <> AscW(Mid(orderedCharacters, i2, 1)) _\n                And Mid(orderedCharacters, i, 1) = Mid(orderedCharacters, i2, 1) Then\n                \'If two distinct characters are equal when case is ignored (e.g. "a" and "A")\n                \'(this is possible only because directive "Option Compare Text" is defined at top of module)\n                \'then only one should be used (either "a" or "A" but not both), so that the Excel sorting\n                \'does not vary depending on sorting option "Ignore case".\n                Exit For\n            End If\n        Next\n        If i2 = i Then\n            \'NO\n            aTemp(AscW(Mid(orderedCharacters, i, 1))) = Format(j, "000")\n            j = j + 1\n        Else\n            \'YES "a" has same weight as "A"\n            aTemp(AscW(Mid(orderedCharacters, i, 1))) = aTemp(AscW(Mid(orderedCharacters, i2, 1)))\n        End If\n    Next\n    \'Last character is for any character of input text which is not in orderedCharacters\n    aTemp(maxAscW) = Format(j, "000")\n\n    getSortableCharacters = aTemp\n\nEnd Function\n\nFunction getOrderedCharactersCurrentLocale(numOfChars As Integer) As String\n\n    \'Build a string of characters, ordered according to the LOCALE order.\n    \'    (NB: to order by LOCALE, the directive "Option Compare Text" must be at the beginning of the module)\n    \'Before sorting, the placed characters are: ChrW(0), ChrW(1), ..., ChrW(numOfChars-1), ChrW(numOfChars).\n    \'Note that some characters are not used: for those characters which have the same sort weight\n    \'    like "a" and "A", only the first one is kept.\n    \'For debug, you may define constdebug=48 so that to use "printable" characters in sOrder:\n    \'    ChrW(48) ("0"), ChrW(49) ("1"), ..., ChrW(numOfChars+47), ChrW(numOfChars+48).\n\n    sOrder = ""\n    constdebug = 0 \'Use 48 to help debugging (ChrW(48) = "0")\n    i = 34\n    Do Until Len(sOrder) = numOfChars\n        Select Case constdebug + i\n            Case 0, 7, 14, 15: i = i + 1\n        End Select\n        sCharacter = ChrW(constdebug + i)\n        \'Search order of character in current locale\n        iOrder = 0\n        For j = 1 To Len(sOrder)\n            If AscW(sCharacter) <> AscW(Mid(sOrder, j, 1)) And sCharacter = Mid(sOrder, j, 1) Then\n                \'If two distinct characters are equal when case is ignored (e.g. "a" and "A")\n                \'("a" = "A" can be true only because directive "Option Compare Text" is defined at top of module)\n                \'then only one should be used (either "a" or "A" but not both), so that the Excel sorting\n                \'does not vary depending on sorting option "Ignore case".\n                iOrder = -1\n                Exit For\n            ElseIf Mid(sOrder, j, 1) <= sCharacter Then\n                \'Compare characters based on the LOCALE order, that\'s possible because\n                \'the directive "Option Compare Text" has been defined.\n                iOrder = j\n            End If\n        Next\n        If iOrder = 0 Then\n            sOrder = ChrW(constdebug + i) & sOrder\n        ElseIf iOrder = Len(sOrder) Then\n            sOrder = sOrder & ChrW(constdebug + i)\n        ElseIf iOrder >= 1 Then\n            sOrder = Left(sOrder, iOrder) & ChrW(constdebug + i) & Mid(sOrder, iOrder + 1)\n        End If\n        i = i + 1\n    Loop\n    \'Last character is for any character of input text which is not in orderedCharacters\n    sOrder = sOrder & ChrW(constdebug + numOfChars)\n\n    getOrderedCharactersCurrentLocale = sOrder\n\nEnd Function\n\nFunction getSortableCode(text As String, SortableCharacters() As String) As String\n\n    \'Used to calculate a sortable text such a way it fits a given order of characters.\n    \'Example: instead of order _, 0-9, Aa-Zz you may want 0-9, Aa-Zz, _\n    \'Will work only if Option Compare Text is defined at the beginning of the module.\n\n    getSortableCode = ""\n    For i = 1 To Len(text)\n        If AscW(Mid(text, i, 1)) < UBound(SortableCharacters) Then\n            If SortableCharacters(AscW(Mid(text, i, 1))) <> "" Then\n                getSortableCode = getSortableCode & SortableCharacters(AscW(Mid(text, i, 1)))\n            Else\n                \'Character has not an order sequence defined -> last in order\n                getSortableCode = getSortableCode & SortableCharacters(UBound(SortableCharacters))\n            End If\n        Else\n            \'Character has not an order sequence defined -> last in order\n            getSortableCode = getSortableCode & SortableCharacters(UBound(SortableCharacters))\n        End If\n    Next\n\n    \'For two texts "a1" and "A1" having the same sortable code, appending the original text allows using the sort option "Ignore Case"/"Respecter la casse"\n    getSortableCode = getSortableCode & " " & text\n\nEnd Function\n
Run Code Online (Sandbox Code Playgroud)\n