【问题标题】:Create multiple areas via VBA in Excel在 Excel 中通过 VBA 创建多个区域
【发布时间】:2021-09-14 14:38:37
【问题描述】:

我需要在 Excel 中为多个范围设置轮廓边框格式。

这样的工作:

Union(Range("A1"), Range("B3")).BorderAround(...)

但是一旦 Ranges 接触,它们就会合并成一个范围,而边框将围绕整个合并的范围。使用Range("A1,A2") 方式有效,但在区域数方面受到限制并且不会工作。

在给定两个范围 r1、r2 的情况下,有什么方法可以将它们作为单个范围中的单独区域,无论它们是否接触?

编辑: 一点澄清:

我可能有一千个我想给边界的区域,有时是触摸的。我想获得一个包含所有(正确区域)的单个范围并在该单个范围上执行操作。原因:

  1. 我可以更清晰地从函数返回范围,例如GetRangesThatNeedsBorder().
  2. 一次不做一个区域的性能原因。
  3. 该功能的用户感觉更正确、更直观。

由于长度限制,我不想使用联合范围的“字符串方法”。我考虑过的几个选项:

  • 使用联合,但创建两个单独的范围,以一种条纹模式(仅在特定情况下有效),并执行两次调用。
  • 使用字符串方法,但在适当的位置拆分字符串。

编辑 2: 做正确的事:

Public Sub test()
    Dim r As Range
    Set r = Union(Range("A1:A3"), Range("B1"), Range("B3"), Range("C1:C3"))
    Call r.BorderAround(2)
End Sub

失败,合并 A1:A4:

Public Sub test()
    Dim r As Range
    Set r = Union(Range("A1:A3"), Range("B1"), Range("B3"), Range("C1:C3"), Range("A4"))
    Call r.BorderAround(2)
End Sub

【问题讨论】:

  • 为什么不这样做FOR EACH ...
  • @DirkReichel,我认为问题在于,如果您执行For Each Area in Range...,它会将相邻的单元格合并到一个区域中。另一方面,For Each Cell 会在每个单元格周围设置边框。
  • 鉴于您对我的回答的评论,并重新阅读您的问题,我的主要问题是您在谈论多少范围变量?
  • 如果我没听错的话,A1:A3、B1、B3 和 C1:C3 看起来就像 B2 和 A1:C3 周围的边界......对吗?
  • @DirkReichel 我想我知道你要去哪里,但没有。这将给出 4 个区域。这些区域只有在可以制成单个矩形时才被连接起来。

标签: vba excel


【解决方案1】:

如果我理解正确,您想以"A1,A2:A3,B1:B3,C3" 之类的字符串中的地址开头。在这种情况下,这应该有效:

Sub OutlineManyCells()
Dim ws As Excel.Worksheet
Dim RangeAddress As String
Dim RangeAddresses As Variant
Dim i As Long

RangeAddress = "A1,A2:A3,B1:B3,C3"
Set ws = ActiveSheet
RangeAddresses = Split(RangeAddress, ",")
    For i = LBound(RangeAddresses) To UBound(RangeAddresses)
        ws.Range(RangeAddresses(i)).BorderAround LineStyle:=2
    Next i
End Sub

这解决了 A1、A2 和 A3 的问题,例如合并到 For Each Area in Range("A1,A2:A3,B1:B3,C3") 中的单个区域,同时让您放置围绕连续单元组的边界。

对于我的一些相关的博客文章,请参阅:http://yoursumbuddy.com/undo-selections-selectracker/

【讨论】:

  • 不,恰恰相反。 Range("A1,A2:A3,B1:B3,C3").BorderAround 确实工作。问题是我没有字符串格式的范围,而是单独的范围。我会尽快更新我的问题。
  • 查看您的更新,它确认了我认为是开头所述的问题,即字符串地址长度的限制。我的回答让你使用更长的字符串。由于您描述的联合范围的问题,我看不到任何使用字符串的方法。
  • 但是将范围作为范围,他可以使用ParamArray,然后按照我的评论中提到的那样运行For Each ...,还是我错了?
  • @DirkReichel 出于性能原因,我想避免每种情况(因为它在任何其他地方都可以使用单个范围“感觉”更好)。
【解决方案2】:

老问题,但我今天需要答案。找不到任何其他解决方案,所以我自己创建了一个。下面的代码可以从任意长度的 Range 字符串创建 Range 对象。

Function RangeFromString(iSh As Worksheet, ByVal sLongString As String, Optional lDepth As Long = 1) As Range
    Dim lPos As Long, sName As String
    If Len(sLongString) <= 255 Then
        Set RangeFromString = iSh.Range(sLongString)
    Else
        sName = "RFS_" & lDepth
        lPos = InStrRev(sLongString, ",", 256)
        iSh.Names.Add sName, iSh.Range(Left(sLongString, lPos - 1))
        Set RangeFromString = RangeFromString(iSh, sName & "," & Mid(sLongString, lPos + 1), lDepth + 1)
        iSh.Names(sName).Delete
    End If
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多