Excel VBA:组织选择.地址字符串



下面的子代码完全符合我的要求,但前提是用户从左到右选择列

基本上,它在选定的每一列的左边插入一列,并应用指定的格式。

我的问题是,是否有一个内置的方法,我可以用它来组织选择的地址,以便列从左到右排序?

Sub InsertColumns()
Dim Columns() As String
Dim x As Integer
ReDim Columns(UBound(Split(Selection.Address, ",")))
'Organize the string before splitting it into an array?
Columns = Split(Selection.Address, ",")
'Maybe a function to sort the array?
For x = 0 To UBound(Columns)
    Range(Columns(x)).Offset(, x).Select 'Used for debugging
    Range(Columns(x)).Offset(, x).Insert
    With Range(Columns(x)).Offset(, x)
        .ColumnWidth = 1
        .NumberFormat = "@"
        .HorizontalAlignment = xlLeft
        .Borders(xlDiagonalDown).LineStyle = xlNone
        .Borders(xlDiagonalUp).LineStyle = xlNone
        .Borders(xlEdgeLeft).LineStyle = xlNone
        .Borders(xlEdgeTop).LineStyle = xlNone
        .Borders(xlEdgeBottom).LineStyle = xlNone
        .Borders(xlEdgeRight).LineStyle = xlNone
        .Borders(xlInsideVertical).LineStyle = xlNone
        .Borders(xlInsideHorizontal).LineStyle = xlNone
    End With
Next
End Sub

指出:

选择对象只算作1列,我还没有想出一种方法来遍历每一列而不使用地址。如果有其他可行的方法,我愿意听取各种建议。

我利用excel的行为将内容向右推送,并将选择保留在它所在的位置,以便将格式应用于"new"列。我不知道如何获得最近通过引用插入的列。例如,像下面这样的东西可以工作吗?

Dim NewCol as Dolumn
Set NewCol = Range(columns(x).Offset(, x).Insert

我使用数学的力量来确保列被正确插入。在添加列时,需要对后面的列进行偏移,以确保移动的列数正确。这就是为什么x被用来抓取起始列,并被用来按所需的量偏移所选内容。

我完全可以编写代码来解析字符串或函数来排序数组。我正在寻找更多的内置方法来做到这一点。

再次,子程序完全按照预期工作。我真的需要找到一种方法来补偿那些不遵循指导的用户。任何想法感谢!

EDIT1:地址字符串将包含如下地址:

$H:$H,$I:$I,$J:$J,$K:$K,$L:$L,$M:$M

如果您不选择从左到右,地址将按照选择列的顺序填充。如果我按顺序选择D F E列,地址是

$D:$D,$F:$F,$E:$E

而不是我想要的D, E, F的字母顺序(从左到右)

Edit2:

我得到一个选择是一个范围对象。我想强调的是:

Sub adsfd()
Dim a As Range
Set a = Selection
Debug.Print a.Columns.Count
End Sub

在这里,输出文本是1,因为在选择中看不到单独的列。

区域也可以:

Sub adsfd()
Dim a As Range
Set a = Selection
Debug.Print a.areas.count
End Sub

这显示了正确的列数。这里的问题是,它们仍然是无序的

我也想强调一下——我可以做到的。我现在的问题是"我该如何做到这一点",而是"是否有一种内置的方式来访问从左到右的选择中的列。"

dim a as range
for each a in selection
    'This cycles through independent cells. Which is not what I want
next a

到目前为止,最好的答案仍然需要遍历选择中的每个单元格。

如果这是用户选择的方式,则从右到左执行,但它似乎仍然达到了既定的目标-在所选的每个列的左侧插入一列并对其进行格式化。

Sub inscol()
    Dim rCol As Range
    Dim rNew As Range
    For Each rCol In Selection.Columns
        rCol.Insert
        With rCol.Offset(, -1)
            .ColumnWidth = 1
            .NumberFormat = "@"
            .HorizontalAlignment = xlLeft
            .Borders(xlDiagonalDown).LineStyle = xlNone
            .Borders(xlDiagonalUp).LineStyle = xlNone
            .Borders(xlEdgeLeft).LineStyle = xlNone
            .Borders(xlEdgeTop).LineStyle = xlNone
            .Borders(xlEdgeBottom).LineStyle = xlNone
            .Borders(xlEdgeRight).LineStyle = xlNone
            .Borders(xlInsideVertical).LineStyle = xlNone
            .Borders(xlInsideHorizontal).LineStyle = xlNone
        End With
    Next rCol
End Sub

您可以使用一个函数(例如下面)来找到最右边的选定列,然后从该列向后工作:

Sub Tester()
Dim MaxCol As Long, c As Long
Dim rng As Range
Set rng = Selection.EntireColumn
MaxCol = LastCol(rng)
For c = MaxCol To 1 Step -1
    If Not Application.Intersect(Selection.Parent.Columns(c), rng) _
                                                    Is Nothing Then
        'insert your new column
    End If
Next c
End Sub
Function LastCol(rng As Range) As Long
    Dim a As Range, c As Range
    LastCol = 0
    For Each a In rng.Areas
        For Each c In a.Columns
            If c.Column > LastCol Then LastCol = c.Column
        Next c
    Next a
End Function

最新更新