【问题标题】:Excel VBA is changing the Range I setExcel VBA 正在更改我设置的范围
【发布时间】:2022-07-15 22:33:24
【问题描述】:

我正在尝试设置以下范围:

Range("F3:F102,J3:J102,N3:N102,R3:R102,V3:V102,Z3:Z102,AD3:AD102,AH3:AH102,AL3:AL102,AP3:AP102,AT3:AT102,AX3:AX102,BB3:BB102,BF3:BF102,BJ3:BJ102,BN3:BN102,BR3:BR102,BV3:BV102,BZ3:BZ102,CD3:CD102")

我尝试使用 For 循环和 Application.Union 迭代地构建它,而不是手动输入 Range,因为我必须构建许多类似的范围。

Sub Build_Range()

    Dim FirstParamCol, ParamCells                             As Range
    Dim i                                                     As Integer

    Application.ScreenUpdating = False
    Application.EnableEvents = False 'avoid infinite loop if any target cell is changed

    Set ParamCells = Range("F3:F102") 'There 20 different "Parameter" columns, the first one being Column F (column 6)
    
    'Note: After column F (6), the other 19 columns are 4 columns apart each (j/10, N/14, ...)
    'so I looped for i = 1 to 19 and used the formula column = 6 (column F) + i * 4:
    
    For i = 1 To 19 'There are other 19 "Parameter" columns
        Set ParamCells = Application.union(ParamCells, Range(ActiveSheet.Cells(3, 6 + 4 * i), ActiveSheet.Cells(102, 6 + 4 * i)))
    Next i
    MsgBox ParamCells.Address 'TODO: For Debugging only
    Range("B103").Value = ParamCells.Address
    
Exitsub:
    Application.EnableEvents = True
    Application.ScreenUpdating = True
  
End Sub

我得到以下范围,但缺少最后一列(“CD3:CD102”):

Range("F3:F102,J3:J102,N3:N102,R3:R102,V3:V102,Z3:Z102,AD3:AD102,AH3:AH102,AL3:AL102,AP3:AP102,AT3:AT102,AX3:AX102,BB3:BB102,BF3:BF102,BJ3:BJ102,BN3:BN102,BR3:BR102,BV3:BV102,BZ3:BZ102")

我尝试增加 For 循环中最后一个 i 的值,但得到的范围与上述相同。

我尝试使用以下代码手动设置范围。我得到与上面相同的范围,再次错过了最后一列:

Sub Build_Range_2()

    Dim ParamCells                             As Range
    
    Set ParamCells = Range("F3:F102,J3:J102,N3:N102,R3:R102,V3:V102,Z3:Z102,AD3:AD102,AH3:AH102,AL3:AL102,AP3:AP102,AT3:AT102,AX3:AX102,BB3:BB102,BF3:BF102,BJ3:BJ102,BN3:BN102,BR3:BR102,BV3:BV102,BZ3:BZ102,CD3:CD102")
    MsgBox ParamCells.Address
    Range("B103").Value = ParamCells.Address
  
End Sub

我搜索了它是否是 Range 的最大大小限制或类似的东西,但我找不到任何东西。

我在 MsgBox 和 Range("B103").Value 上打印构建的 Range,仅用于调试目的(我不需要显示 Range,而是使用它/使用它)。

【问题讨论】:

  • 您是否尝试过使用全部范围然后只使用您需要的东西,例如 F3:CD102...

标签: excel vba


【解决方案1】:

首先,好的信息是您构建该范围的代码可以正常工作!

插入ParamCells.Select 并检查它选择的内容。即使"CD3:CD102" 也不会出现在地址ParamCells.Address 中,它是ParamCells 范围的一部分。

问题是.Address 被限制为 255 个字符。

如果比较,您可以轻松检查

Debug.Print ParamCells.Address
Debug.Print ParamCells.Address(False, False) 
$F$3:$F$102,$J$3:$J$102,$N$3:$N$102,$R$3:$R$102,$V$3:$V$102,$Z$3:$Z$102,$AD$3:$AD$102,$AH$3:$AH$102,$AL$3:$AL$102,$AP$3:$AP$102,$AT$3:$AT$102,$AX$3:$AX$102,$BB$3:$BB$102,$BF$3:$BF$102,$BJ$3:$BJ$102,$BN$3:$BN$102,$BR$3:$BR$102,$BV$3:$BV$102,$BZ$3:$BZ$102
F3:F102,J3:J102,N3:N102,R3:R102,V3:V102,Z3:Z102,AD3:AD102,AH3:AH102,AL3:AL102,AP3:AP102,AT3:AT102,AX3:AX102,BB3:BB102,BF3:BF102,BJ3:BJ102,BN3:BN102,BR3:BR102,BV3:BV102,BZ3:BZ102,CD3:CD102

第一个有 253 个字符,在字符串中添加 CD3:CD102 会超过 255,因此会被截断。第二个没有绝对地址,因此它更短,所以最后你可以看到…,BZ3:BZ102,CD3:CD102 CD3:CD102 实际上在范围内。

因此,无论何时使用 ParamCells,它都适用于整个范围,无论 ParamCells.Address 被截断为什么。

所以问题是您需要显示地址吗?然后你需要一些解决方法(取决于你的实际目标是什么)。还是只是调试您的代码然后使用ParamCells.Select 来检查它。

如果要输出ParamCells vor 验证的实际地址,可以通过循环ParamCells.Areas 来实现。

Dim AddrOfParamCells As String
Dim Area As Range
For Each Area In ParamCells.Areas
    AddrOfParamCells = IIf(AddrOfParamCells <> vbNullString, AddrOfParamCells & ",", vbNullString) & Area.Address
Next Area

Debug.Print AddrOfParamCells

请注意,此地址只能用于验证,但不能用于构建像Set TestRange = Range(AddrOfParamCells) 这样的范围,因为它超过了 255 个字符。

【讨论】:

  • 非常感谢 PEH。我想象有某种限制,但找不到有关它的文档,也没有想到限制在 .Address 上,但实际上该范围是正确构建的。谢谢!
【解决方案2】:

.Address 限制为 255 个字符...但您可以使用字符串来处理。

    Sub Build_Range()

    Dim FirstParamCol   As Range
    Dim ParamCells      As Range
    Dim i               As Integer
    Dim StrRange        As String 'String to store the address of ParamCells

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    
    'Is not a good practice to hard code... but it is your code, and
    'You will debug this... in the future!
    Set ParamCells = Range("F3:F102")
    StrRange = ParamCells.Address(1, 1, xlA1, 0, 0)
    'To find some help in .Address:
    'https://docs.microsoft.com/en-us/office/vba/api/excel.range.address
    
    For i = 1 To 19
        'Here you store the address.
        'Again, don't like to hard code... but the & "," & in this point it is necessary
        StrRange = StrRange & "," & Range(ActiveSheet.Cells(3, 6 + 4 * i), ActiveSheet.Cells(102, 6 + 4 * i)).Address(1, 1, xlA1, 0, 0)
        'I Keep youy var, if you want to do something with the range.
        'You can not print the full address in the immediate window, but
        'You can still use the full range.
        Set ParamCells = Application.Union(ParamCells, Range(ActiveSheet.Cells(3, 6 + 4 * i), ActiveSheet.Cells(102, 6 + 4 * i)))
    Next i
    
    'Just to check if is working.
    'ParamCells.Select
    
    MsgBox ParamCells.Address 'TODO: For Debugging only
    'No use this
    'Range("B103").Value = ParamCells.Address
    'Use this:
    Range("B103").Value = ParamCells.Address
    
Exitsub:
    Application.EnableEvents = True
    Application.ScreenUpdating = True
  
End Sub

【讨论】:

  • 好吧,我认为 OP 想验证范围是否正确构建并且构建单独的 StrRange 是没用的,如果你真的想调试/检查你的循环是否正确构建了 ParamCells。因为您验证的是字符串而不是范围。 • 更好的方法是遍历ParamCells.Areas 的所有区域并将它们的地址连接到一个字符串。这样您就可以证明ParamCells 是实际范围。看我的回答。
  • 非常感谢埃尔伯特。正如 PEH 在他的评论中所说,单独的 StrRange 对我不起作用,因为我需要 Range。并且只需要验证它是否正确构建。如果 PEH 之前没有回复,您的回答也可以让我弄清楚发生了什么,因为您还提到 .Address 限制为 255 个字符,所以我赞成您的回答。无论如何,感谢您花时间提供答案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
相关资源
最近更新 更多