前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >在VBA中对数组排序的代码

在VBA中对数组排序的代码

作者头像
fanjy
发布于 2023-09-21 11:40:46
发布于 2023-09-21 11:40:46
1.2K00
代码可运行
举报
文章被收录于专栏:完美Excel完美Excel
运行总次数:0
代码可运行

标签:VBA

这是一段非常好的代码,来自ozgrid.com,可以使用它来快速排序VBA中的数组。

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
'对一维或二维数组排序.
'二维数组可以通过传递适当的列编号作为sortKeys参数来指定其排序键.
'函数传递一个引用,因此将对原始数组进行变异.
'如果不需要,必须传递一份副本.
'
'示例使用:
' sortArray myArray                 - 一维数组
' sortArray myArray, 2              - 二维数组, 单个排序键
' sortArray myArray, Array(2,3,1)   - 二维数组,多个排序键
Function sortArray(ByRef arr As Variant, Optional ByRef sortKeys As Variant = Null, _
 Optional ByVal hasHeaders As Boolean = False, Optional sortDirection As XlSortOrder = xlAscending) As Variant
 Dim mid&, i&, j&, k&, x&, y&, sortMode&, padLen&, padOffset& 'As Long
 Dim arr1, arr2, v, v1, v2 'As Variant
 Dim head, tmp, sortCols() 'As Variant
 Dim re As Object, matches As Object
 Dim s As String
 
 If UBound(arr) - LBound(arr) = 0 Then
   sortArray = arr
   Exit Function
 End If
 If sortDirection <> 1 Then
   sortDirection = -1
   Set re = CreateObject("VBScript.RegExp")
   padLen = 50: re.Global = True: re.MultiLine = True: re.IgnoreCase = True: re.Pattern = "[0-9]+"
   On Error Resume Next
   i = UBound(arr, 2)
   If Err.Number <> 0 Then
     sortMode = 1 '不是二维数组
     If hasHeaders Then
       ReDim tmp(LBound(arr) To UBound(arr) - 1)
       ReDim head(1 To 1)
       For i = LBound(arr) To UBound(arr)
         If i = LBound(arr) Then
           If TypeOf arr(LBound(arr)) Is Object  Then Set head(1) = arr(LBound(arr)) Else head(1) = arr(LBound(arr))
         Else
           If TypeOf arr(i) Is Object  Then Set tmp(i - 1) = arr(i) Else tmp(i - 1) = arr(i)
         End If
       Next i
       arr = tmp
       Erase tmp
     End If
   Else
     sortMode = 2
     If hasHeaders Then
       ReDim tmp(LBound(arr) To (UBound(arr) - 1), LBound(arr, 2) To UBound(arr, 2))
       ReDim head(1 To 1, LBound(arr, 2) To UBound(arr, 2))
       For i = LBound(arr) To UBound(arr)
         For j = LBound(arr, 2) To UBound(arr, 2)
           If i = LBound(arr) Then
             If TypeOf arr(LBound(arr), j) Is Object  Then Set head(1, j) = arr(LBound(arr), j) Else head(1, j) = arr(LBound(arr), j)
           Else
             If TypeOf arr(i, j) Is Object  Then Set tmp(i - 1, j) = arr(i, j) Else tmp(i - 1, j) = arr(i, j)
           End If
         Next j
       Next i
       arr = tmp
       Erase tmp
     End If
   End If
   On Error GoTo 0
   If sortMode = 1 Then
     sortCols = Array(LBound(arr))
   ElseIf IsNumeric(sortKeys) Then
     tmp = Array(CLng(sortKeys))
   ElseIf IsArray(sortKeys) Then
     i = -1
     On Error Resume Next
     i = UBound(sortKeys, 2)
     On Error GoTo 0
     If i = -1 Then
       tmp = sortKeys
     Else
       If IsNumeric(sortKeys(LBound(sortKeys), LBound(sortKeys, 2))) Then
         tmp = Array(CLng(sortKeys(LBound(sortKeys), LBound(sortKeys, 2))))
       Else
         tmp = Array(LBound(arr, 2))
       End If
     End If
   Else
     tmp = Array(LBound(arr, 2))
   End If
   If sortMode = 2 Then
     ReDim sortCols(LBound(tmp))
     sortCols(LBound(tmp)) = LBound(arr, 2)
     j = LBound(sortCols) - 1
     For i = LBound(tmp) To UBound(tmp)
       If IsNumeric(tmp(i)) Then
         If CLng(tmp(i)) >= LBound(arr, 2) And CLng(tmp(i)) <= UBound(arr, 2) Then j = j + 1
         If j > UBound(sortCols) Then 
           ReDim Preserve sortCols(LBound(sortCols) To j)
           sortCols(j) = tmp(i)
         End If
       End If
     Next i
     Erase tmp
   End If
   y = LBound(sortCols)
   mid = Int((UBound(arr) + IIf(LBound(arr) = 0, 1, 0)) / 2)
   If mid < LBound(arr) Then mid = LBound(arr)
   If sortMode = 1 Then
     ReDim arr1(LBound(arr) To mid - IIf(LBound(arr) = 0, 1, 0))
     ReDim arr2(LBound(arr) To UBound(arr) - mid)
     j = LBound(arr)
     For i = LBound(arr1) To UBound(arr1)
       If TypeOf arr(j) Is Object  Then
         Set arr1(i) = arr(j)
       Else
         arr1(i) = arr(j)
       End If
       j = j + 1
     Next i
     For i = LBound(arr2) To UBound(arr2)
       If TypeOf arr(j) Is Object  Then
         Set arr2(i) = arr(j)
       Else
         arr2(i) = arr(j)
       End If
       j = j + 1
     Next i
   ElseIf sortMode = 2 Then
     ReDim arr1(LBound(arr) To mid - IIf(LBound(arr) = 0, 1, 0), LBound(arr, 2) To UBound(arr, 2))
     ReDim arr2(LBound(arr) To UBound(arr) - mid, LBound(arr, 2) To UBound(arr, 2))
     j = LBound(arr)
     For i = LBound(arr1) To UBound(arr1)
       For k = LBound(arr1, 2) To UBound(arr1, 2)
         If TypeOf arr(j, k) Is Object  Then
           Set arr1(i, k) = arr(j, k)
         Else
           arr1(i, k) = arr(j, k)
         End If
       Next k
       j = j + 1
     Next i
     For i = LBound(arr2) To UBound(arr2)
       For k = LBound(arr2, 2) To UBound(arr2, 2)
         If TypeOf arr(j, k) Is Object  Then
           Set arr2(i, k) = arr(j, k)
         Else
           arr2(i, k) = arr(j, k)
         End If
       Next k
       j = j + 1
     Next i
   End If
   sortArray arr1, sortCols, , sortDirection '调用自身!!!
   sortArray arr2, sortCols, , sortDirection '再次调用自身!!!
   i = LBound(arr)
   j = LBound(arr1)
   k = LBound(arr2)
   If sortMode = 1 Then
     While j <= UBound(arr1) And k <= UBound(arr2)
     If TypeOf arr1(j) Is Object  Then v1 = ObjPtr(arr1(j)) Else v1 = arr1(j)
     If TypeOf arr2(k) Is Object  Then v2 = ObjPtr(arr2(k)) Else v2 = arr2(k)
     If IsNumeric(v1) Then v1 = CDbl(v1)
     If IsNumeric(v2) Then v2 = CDbl(v2)
     If re.test(v1) And TypeName(v1) <> "Double" Then
       Set matches = re.Execute(v1)
       padOffset = 0
       s = v1
       For Each v In matches
         s = Left(s, v.FirstIndex + padOffset) & Application.Rept("0", (padLen - Len(v))) & VBA.mid(s, v.FirstIndex + padOffset + 1)
         padOffset = (padLen - Len(v))
       Next v
       v1 = s
       s = vbNullString
     End If
     If re.test(v2) And TypeName(v2) <> "Double" Then
       Set matches = re.Execute(v2)
       padOffset = 0
       s = v2
       For Each v In matches
         s = Left(s, v.FirstIndex + padOffset) & Application.Rept("0", (padLen - Len(v))) & VBA.mid(s, v.FirstIndex + padOffset + 1)
         padOffset = (padLen - Len(v))
       Next v
       v2 = s
       s = vbNullString
     End If
     If IsNumeric(v1) And IsNumeric(v2) Then
       If (CDbl(v1) - CDbl(v2)) * sortDirection <= 0 Then
         If TypeOf arr1(j) Is Object  Then Set arr(i) = arr1(j) Else arr(i) = arr1(j)
           j = j + 1
         Else
           If TypeOf arr2(k) Is Object  Then Set arr(i) = arr2(k) Else arr(i) = arr2(k)
           k = k + 1
         End If
       ElseIf StrComp(v1, v2, vbTextCompare) * sortDirection <= 0 Then
         If TypeOf arr1(j) Is Object  Then
           Set arr(i) = arr1(j)
         Else
           arr(i) = arr1(j)
         End If
         j = j + 1
       Else
         If TypeOf arr2(k) Is Object  Then
           Set arr(i) = arr2(k)
         Else
           arr(i) = arr2(k)
         End If
           k = k + 1
       End If
       i = i + 1
     Wend
   While j <= UBound(arr1)
     If TypeOf arr1(j) Is Object  Then
       Set arr(i) = arr1(j)
     Else
       arr(i) = arr1(j)
     End If
     j = j + 1
     i = i + 1
   Wend
   While k <= UBound(arr2)
     If TypeOf arr2(k) Is Object  Then
       Set arr(i) = arr2(k)
     Else
       arr(i) = arr2(k)
     End If
     k = k + 1
     i = i + 1
   Wend
 ElseIf sortMode = 2 Then
   While j <= UBound(arr1) And k <= UBound(arr2)
     If TypeOf arr1(j, sortCols(y)) Is Object  Then v1 = ObjPtr(arr1(j,sortCols(y))) Else v1 = arr1(j, sortCols(y))
     If TypeOf arr2(k, sortCols(y)) Is Object  Then v2 = ObjPtr(arr2(k,sortCols(y))) Else v2 = arr2(k, sortCols(y))
     If IsNumeric(v1) Then v1 = CDbl(v1)
     If IsNumeric(v2) Then v2 = CDbl(v2)
     If re.test(v1) And TypeName(v1) <> "Double" Then
       Set matches = re.Execute(v1)
       padOffset = 0
       s = v1
       For Each v In matches
         s = Left(s, v.FirstIndex + padOffset) & Application.Rept("0", (padLen - Len(v))) & VBA.mid(s, v.FirstIndex + padOffset + 1)
         padOffset = (padLen - Len(v))
       Next v
       v1 = s
       s = vbNullString
     End If
     If re.test(v2) And TypeName(v2) <> "Double" Then
       Set matches = re.Execute(v2)
       padOffset = 0
       s = v2
       For Each v In matches
         s = Left(s, v.FirstIndex + padOffset) & Application.Rept("0", (padLen - Len(v))) & VBA.mid(s, v.FirstIndex + padOffset + 1)
         padOffset = (padLen - Len(v))
       Next v
       v2 = s
       s = vbNullString
     End If
     If IsNumeric(v1) And IsNumeric(v2) Then
     If (CDbl(v1) - CDbl(v2)) * sortDirection < 0 Or (v1 = v2 And UBound(sortCols) = y) Then
     For x = LBound(arr1, 2) To UBound(arr1, 2)
       If TypeOf arr1(j, x) Is Object  Then
         Set arr(i, x) = arr1(j, x)
       Else
         arr(i, x) = arr1(j, x)
       End If
     Next x
     j = j + 1
     y = LBound(sortCols)
   ElseIf (CDbl(v1) - CDbl(v2)) * sortDirection > 0 Then
     For x = LBound(arr2, 2) To UBound(arr2, 2)
       If TypeOf arr2(k, x) Is Object  Then
         Set arr(i, x) = arr2(k, x)
       Else
         arr(i, x) = arr2(k,x)
       End If
     Next x
     k = k + 1
     y = LBound(sortCols)
   Else
     i = i - 1
     y = y + 1
   End If
 ElseIf StrComp(v1, v2, vbTextCompare) * sortDirection < 0 _
    Or (StrComp(v1, v2, vbTextCompare) = 0 And UBound(sortCols) = y) Then
   For x = LBound(arr1, 2) To UBound(arr1, 2)
     If TypeOf arr1(j, x) Is Object  Then
       Set arr(i, x) = arr1(j, x)
     Else
       arr(i, x) = arr1(j, x)
     End If
   Next x
   j = j + 1
   y = LBound(sortCols)
 ElseIf StrComp(v1, v2, vbTextCompare) * sortDirection > 0 Then
   For x = LBound(arr2, 2) To UBound(arr2, 2)
     If TypeOf arr2(k, x) Is Object  Then
       Set arr(i, x) = arr2(k, x)
     Else
       arr(i, x) = arr2(k, x)
     End If
   Next x
   k = k + 1
   y = LBound(sortCols)
 Else
   i = i - 1
   y = y + 1
 End If
 i = i + 1
 Wend
 While j <= UBound(arr1)
   For x = LBound(arr1, 2) To UBound(arr1, 2)
     If TypeOf arr1(j, x) Is Object  Then
       Set arr(i, x) = arr1(j, x)
     Else
       arr(i, x) = arr1(j, x)
     End If
   Next x
   j = j + 1
   i = i + 1
 Wend
 While k <= UBound(arr2)
   For x = LBound(arr2, 2) To UBound(arr2, 2)
     If TypeOf arr2(k, x) Is Object  Then
       Set arr(i, x) = arr2(k, x)
     Else
       arr(i, x) = arr2(k, x)
     End If
   Next x
   k = k + 1
   i = i + 1
 Wend
 End If
 If hasHeaders Then
   If sortMode = 1 Then
     '1d
     ReDim tmp(LBound(arr) To UBound(arr) + 1)
     If TypeOf head(1) Is Object  Then Set tmp(LBound(tmp)) = head(1) Else tmp(LBound(tmp)) = head(1)
     For i = LBound(arr) To UBound(arr)
       If TypeOf arr(i) Is Object  Then
         Set tmp(i + 1) = arr(i)
       Else
         tmp(i + 1) = arr(i)
       End If
     Next i
   Else
     '2d
     ReDim tmp(LBound(arr) To UBound(arr) + 1, LBound(arr, 2) To UBound(arr, 2))
     For i = LBound(tmp) To UBound(tmp)
       For j = LBound(tmp, 2) To UBound(tmp, 2)
         If i = LBound(tmp) Then
           If TypeOf head(1, j) Is Object  Then Set tmp(i, j) = head(1, j) Else tmp(i, j) = head(1, j)
         Else
           If TypeOf arr(i - 1, j) Is Object  Then
             Set tmp(i, j) = arr(i - 1, j)
           Else
             tmp(i, j) = arr(i - 1, j)
           End If
         End If
       Next
     Next i
   End If
   arr = tmp
 End If
 Set re = Nothing
 Set matches = Nothing
 v1 = Empty
 v2 = Empty
 On Error Resume Next
 Erase sortCols
 Erase arr1
 Erase arr2
 Erase tmp
 On Error GoTo 0
 sortArray = arr
End Function

下面是一个如何处理包含数字的字符串排序的小演示(可以使用自动筛选来查看默认排序与排序代码的结果对比):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Sub smartNumberSort()
 Dim a, i&
 ReDim a(1 To 500)
 a(1) = "Key"
 For i = 2 To UBound(a)
   a(i) = Chr(Int((25 * Rnd) + 65)) & " " & Int((100 * Rnd) + 1)
 Next i
 sortArray a, hasHeaders:=True ', sortDirection:=xlDescending '取消注释以查看反向排序
 ActiveSheet.UsedRange.ClearContents
 With Range("a1").Resize(UBound(a))
   .Value = Application.Transpose(a)
   .AutoFilter
 End With
End Sub

欢迎在下面留言,完善本文内容,让更多的人学到更完美的知识。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-16 06:30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 完美Excel 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
ggplot2优雅绘制蛋白结构域与基因结构图
❝小编很久之前写过一系列基因家族数据可视化的文档,最近对基因家族数据可视化又有了新的认识下面来绘制这一类文章里面的一张常用图,下面来看具体操作 ❞ 绘制进化树 tree <- read.newick("tree.nwk",node.label = "support") %>% ggtree(branch.length = "none")+ theme_void()+ theme(legend.title=element_blank(), legend.position =
R语言数据分析指南
2022/09/21
1.9K0
ggplot2优雅绘制蛋白结构域与基因结构图
漂亮的单细胞多组火山图
《Single-cell transcriptome analysis reveals the association between histone lactylation and cisplatin resistance in bladder cancer 》
用户11414625
2024/12/20
1070
漂亮的单细胞多组火山图
生物信息数据分析教程视频——13-3种R包(DESeq2、edgeR和limma)进行RNAseq的差异表达分析与比较
视频地址:http://mpvideo.qpic.cn/0bc3zeaakaaalqalwhjtmzrvbsodaxeqabia.f10002.mp4? 参考文章: 超详细的DESeq2和edg
DoubleHelix
2022/12/15
1.4K0
生物信息数据分析教程视频——13-3种R包(DESeq2、edgeR和limma)进行RNAseq的差异表达分析与比较
多分组差异分析结果的两种展示形式
最近分析了一批RNA-seq的测序数据,发现DEseq2分析后有多了比较组。之前我们会绘制多个火山图或Upset图去呈现结果。但是,由于这两种方式被大家用太多了,所以我们想换几种另外的展示方式。我们在网上差了很多资料,其中有两个图个人感觉很不错,于是,就有了这一期的文案。下面我们直接进入今天的主题分享:
生信菜鸟团
2024/05/20
5220
多分组差异分析结果的两种展示形式
ggplot2绘制突变全景图
附件下载地址:https://ehoonline.biomedcentral.com/articles/10.1186/s40164-021-00200-x
医学和生信笔记
2022/11/15
1.2K0
ggplot2绘制突变全景图
ggplot2优雅绘制多组旭日图
有需要学习数据可视化的朋友,欢迎到小编的「淘宝店铺」 「R语言数据分析指南」下单购买,内容主要包括各种「高分论文的图表分析复现以及一些个性化图表的绘制」均包含数据+代码。购买会员文档后微信发小编订单号即邀请进新的会员交流群。
R语言数据分析指南
2024/03/20
5210
ggplot2优雅绘制多组旭日图
一网打尽转录组差异分析!!!
差异分析在转录组数据分析中占据着举足轻重的地位,是揭示基因表达变化的关键步骤。然而,面对众多如DESeq2、limma和edgeR等转录组分析R包,分析人员常常面临选择困境。本文旨在深入探讨这些常用差异分析R包的特点、优劣,以及它们与t检验/Wilcox秩和检验(Wilcox-rank-sum test)在差异分析结果上的异同点。
生信学习者
2024/06/11
4580
一网打尽转录组差异分析!!!
没想到修个火山图这么麻烦
MAplot转录组差异基因表达展示_maplot r语言_TS的美梦的博客-CSDN博客自己也顺着这线索另外找了教程
生信菜鸟团
2023/09/09
7050
没想到修个火山图这么麻烦
ggplot2优雅的绘制森林图
❝本节来介绍如何使用ggplot2来绘制森林图,下面通过一个小例子来进行展示 ❞ 加载R包 library(tidyverse) 导入数据 unicox <- read_csv("AKT3_mRNA_OS_pancan_unicox.csv") 绘制森林图 p1 <- ggplot(unicox,aes(HR_log, cancer, col=Type))+ geom_point(aes(size=-log10(p.value)))+ geom_errorbarh(aes(xmax =u
R语言数据分析指南
2022/09/21
1.5K0
ggplot2优雅的绘制森林图
NC图表绘制-ggplot2绘制多组填充热图
R语言数据分析指南
2024/04/02
1600
NC图表绘制-ggplot2绘制多组填充热图
R自定义构建函数绘制相关性条形图
构建好绘图函数后让我们来进行可视化的操作,由于原始数据较多在此我们筛选一部分数据进行可视化操作
R语言数据分析指南
2022/09/21
4500
R自定义构建函数绘制相关性条形图
TCGA数据挖掘(四):表达差异分析(4)
在之前我们的文章:TCGA数据挖掘(三):表达差异分析中,我们利用的是TCGAbiolinks包中的TCGAanalyze_DEA函数进行差异表达分析,我们也提到可以选择基于limma或edgeR包进行分析,TCGA数据挖掘(三):表达差异分析这一讲中我们利用的是edgeR包,之后我们在文章:TCGA数据挖掘(四):表达差异分析(2)和TCGA数据挖掘(四):表达差异分析(3)中分别也介绍了其他方法的差异分析,包括edgeR和DESeq包,今天这一讲,我们就利用TCGAbiolinks包中的TCGAanalyze_DEA函数基于limma包进行差异分析。
DoubleHelix
2019/09/18
4.6K0
TCGA数据挖掘(四):表达差异分析(4)
ggplot2优雅的绘制配对气泡图
Step1. R包和数据加载、主题设置 测试数据在: 链接:https://pan.baidu.com/s/1MuMgMZZCcdO-IGS7_ysfkQ?pwd=1234 提取码:1234 libr
生信菜鸟团
2023/08/23
4990
ggplot2优雅的绘制配对气泡图
ggplot2轻松绘制误差线点图与箱线图
R语言数据分析指南
2023/08/18
5330
ggplot2轻松绘制误差线点图与箱线图
三种转录组差异分析方法及区别你会了吗?
在做项目时,曾有小伙伴对我用edgeR进行差异分析筛选出的具体显著差异基因表示质疑,因为发表的文章清楚的说明某个基因是差异基因,但是我edgeR的分析结果并没有表明。在小伙伴的质疑下,我认真看了下文章,发现文章用的是DEseq2进行差异分析。值得注意的是该小伙伴关注的差异基因是一个离散比较大的基因,此处的离散较大可以理解为假定对照组为5,6,7;实验组则为14,13,3的情况。那为什么这个基因在edgeR分析下不是显著差异基因,然而在DEseq2的分析下是差异基因呢?这应该很大程度源于算法判定显著差异基因的区别。接着,我看了关于DEseq2与edgeR区别的描述,发现「edgeR与Deseq2都是基于负二项分布模型做的,两者处理同一组数据时,相同阈值处理大部分基因是一样的,但是也会有一部分基因会因为离散度不同导致差异不同」,如刚刚示例的基因离散度被DEseq2识别为差异,但是不被edgeR识别,所以两种算法获取的差异基因与数目是存在细微区别的。
生信菜鸟团
2022/10/31
5.9K1
三种转录组差异分析方法及区别你会了吗?
文献组图
追风少年i
2025/01/07
640
文献组图
scRNA分析| Seurat堆叠小提琴图不满足? 那就ggplot2 堆叠 各种元素
单细胞常见的可视化方式有DimPlot,FeaturePlot ,DotPlot ,VlnPlot 和 DoHeatmap几种 ,Seurat均可以实现,但文献中的图大多会精美很多。比如
生信补给站
2023/08/25
4.6K0
scRNA分析| Seurat堆叠小提琴图不满足?  那就ggplot2 堆叠 各种元素
带有疾病进展的多分组差异结果如何展示?
此次给绘制的图来自文献《Triple DMARD treatment in early rheumatoid arthritis modulates synovial T cell activation and plasmablast/plasma cell differentiation pathways》,是2017发表的,使用了他们团队自己2016发表的转录组测序数据,所以其实是有两个转录组测序数据集。
生信技能树
2025/01/02
1430
带有疾病进展的多分组差异结果如何展示?
跟着Nature Communications学作图:R语言ggplot2堆积柱形图组合饼状图
https://www.nature.com/articles/s41467-024-45739-5
用户7010445
2024/03/22
3360
跟着Nature Communications学作图:R语言ggplot2堆积柱形图组合饼状图
生物信息数据分析教程视频——07-TCGA数据库:基因的表达探索
视频地址:http://mpvideo.qpic.cn/0b2ewiaakaaahmalygztmbrvbmwdawzaabia.f10002.mp4? 参考文章: 【0代码】单基因泛癌分析教程 视频
DoubleHelix
2022/12/15
7150
推荐阅读
相关推荐
ggplot2优雅绘制蛋白结构域与基因结构图
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档