excel - 将数字划分为用户表单标签中显示的唯一排序数字
问题描述
我想将数字分成唯一的排序数字。例如,数字可以是 127425,我想要 12457 作为结果,这意味着已排序并删除了重复项。我认为最好的例子是解释:
+---------+--------+
| Number | Result |
+---------+--------+
| 127425 | 12457 |
+---------+--------+
| 2784425 | 24578 |
+---------+--------+
| 121 | 12 |
+---------+--------+
| 22222 | 2 |
+---------+--------+
| 9271 | 1279 |
+---------+--------+
最长的结果只能是 123456789。
我不认为我们需要一个数组(没有分隔符),但使用子字符串可能会完成这项工作。我只是不知道从哪里开始,因此没有代码。
欢迎任何想法。谢谢。
解决方案
替代较新的动态数组函数
喜欢上述不错的解决方案,考虑其他方法(通过Byte
数组Filter()
和FilterXML()
函数)总是一个挑战:
Function UniqueDigits(ByVal txt) As String
Dim by() As Byte: by = txt
Dim digits: digits = Array(49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 0) ' equalling Asc values
'a) create 1-based 1-dim array with digit positions
Dim tmp: tmp = Filter(Application.Match(by, digits, 0), 11, False)
'b) get uniques
tmp = Uniques(tmp)
'c) sort it (don't execute before getting uniques)
BubbleSort tmp
'd) return function result
UniqueDigits = Join(tmp, "")
End Function
Function Uniques(arr)
'Note: using FilterXML() available since vers. 2013+
Dim content As String ' replacing "10" referring to zero indexed as 10th digit
content = Replace("<t><s>" & Join(arr, "</s><s>") & "</s></t>", "10", "0")
arr = WorksheetFunction.FilterXML(content, "//s[not(preceding::*=.)]")
Uniques = Application.Transpose(arr)
End Function
Sub BubbleSort(arr)
Dim cnt As Long, nxt As Long, temp
For cnt = LBound(arr) To UBound(arr) - 1
For nxt = cnt + 1 To UBound(arr)
If arr(cnt) > arr(nxt) Then
temp = arr(cnt)
arr(cnt) = arr(nxt)
arr(nxt) = temp
End If
Next nxt
Next cnt
End Sub
进一步的提示:-) tl;dr
...解释
a) 如何将字符串转换为数字数组,b) 如何通过 FilterXML 而不是字典来获取唯一性 c)(执行 BubbleSort 无需进一步解释)。
ad a)
获取纯数字数组的棘手方法将
一串数字转换为单个字符的数组可能需要一些解释。
- 一个字符串(这里
txt
)可以很容易地通过 分配给一个字节数组Dim by() As Byte: by = txt
。(请注意,经典字符将在字节数组中由一对值Asc
表示,其中第二个值主要是0
;因此 digit1
由 49 和 0、502
和 0 到9
57 和 0 表示)。
数字定义在从~>49 到~>57的基于 1 的Asc
值数组中,然后是第 10 项~>48,最后是与每个第二个字节对相关的第 11 项的值。1
9
0
Asc
0
Dim digits: digits = Array(49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 0) ' equalling Asc values
- 通常,该
Match()
函数会搜索指定项以获取其在数组中的相对位置(此处digits
),并将通过以下语法执行:``.
MATCH( lookup_value ,lookup_array, [match_type]) 其中lookup_value参数可以是一个值(数字、文本或逻辑值)或对数字、文本或逻辑值的单元格引用。
一个未记录的特性是,例如2
在 lookup_array 中digits
搜索
,Application.Match(2, digits,0)
您可以使用字节数组作为第一个参数,用作基于 1 的数组模式,其中 VBA 用它们在数字数组中找到的位置Asc
替换当前值。
Application.Match(by, digits, 0)
最后,负过滤通过以下方式删除伴随Asc 0
值(11
加参数False
)
Dim tmp: tmp = Filter(Application.Match(by, digits, 0), 11, False)
ad b)
通过 FilterXML 获取唯一性
WorksheetFunction.FilterXML
该方法需要两个字符串参数的帮助参考
FilterXML(XMLContentString, XPathQueryString)
第一个参数不引用文件,但需要以根节点 (DocumentElement) 开头的有效(“格式良好”)XML 文本字符串,该字符串与以封闭<html>...</html>
标记对开头的 html 结构大致相当。
因此,表示例如数字的格式良好的内容字符串121
可以是:
<t>
<s>1</s>
<s>2</s>
<s>1</s>
</t>
第二个参数(限制为 1024 个字符)必须是有效的XPath 查询字符串,如下所示
"//s[not(preceding::*=.)]"
其中双斜杠//
允许查找s
任何层次结构级别的节点,并且在它之前没有任何*
具有相同值内容的节点的情况下=.
推荐读数
@RonRosenfeld 是涵盖该方法的众多答案的先驱作者,FilterXML
例如拆分字符串单元...。
@JvDV 在使用 FilterXML 从字符串中提取子字符串中写了一个近乎百科全书的概述。
推荐阅读
- r - 将 R 图保存为数值数组对象
- python - matplotlib 中的一个绘图中有很多行
- botframework - 有什么方法可以指定 QnA 对(QnA Maker)中替代问题的顺序?
- css - 冻结动画css上的状态位置
- python - python中有没有办法让拟合数据的幅度与原始数据相匹配
- python - 在 Python 中使用布尔值
- excel - VBA循环通过图表设置图表类型(xlLine),系列重量,系列颜色,图表图例(向下),图表高度和宽度
- python - 仅在按下按钮时播放 OpenCV 视频 TKinter
- android - Flutter 材质抽屉导航到页面
- html - 无法滚动菜单 - 菜单“后面”的内容滚动