使用包含范围变量的变体数组来填充后续通过变量名称引用的范围失败。

huangapple go评论67阅读模式
英文:

Using Variant Array containing Range Variables to populate Ranges to be later referenced by range Variable by name is failing

问题

以下是您提供的代码的翻译部分:

考虑下面的子程序。我几乎找到了我想要的,但还不太对。

需要考虑的已知因素:这个模块声明语句已经设置了每个变量(总共63个 - 我已经删除了大部分以简化下面的示例)作为公共变量,可以随时引用。我已经对修改布尔变量值做了类似的事情,但是由于它们是对象,所以在某些情况下失败了。

For循环正确地提取了相关数据并将其放入每个变体数组中的相应占位符中,这意味着例如StoreStateRng占位符持有表中范围的正确数据,但是当尝试操作存储在占位符内部的实际范围变量时,无法引用。

理论上 - 我本来希望这会在物理上设置*变量"StoreStateRng"*为指定的范围。它确实将rngVars(i)设置为指定的范围,并在监视上检查时给出了Variant/Range类型,但是在同时检查实际变量时,范围变量"StoreStateRng"为空!

'声明语句的摘录

'下面是数组中列出的63个变量中的3个示例
Public Const StoreStateRng_Col As Integer = 23
Public StoreStateRng As Range
Public StoreStateRng_Val As Variant

'在子程序开始处定义的变体数组
Public rngVar As Variant
Public rngVars() As Variant
Public rngVarStr() As Variant
Public rngVarCols() As Variant
Public rngVarColStr() As Variant
Public rngVarVals() As Variant
Public rngVarValStr() As Variant


Sub Get_Ranges()
  Set ws = ThisWorkbook.Sheets(wsNameMain)
  
  rngVars() = Array(StoreStateRng, StoreCityRng, StoreDateRng, StoreNumRng)
  rngVarStr() = Array("StoreStateRng", "StoreCityRng", "StoreDateRng", "StoreNumRng")
  rngVarCols() = Array(StoreStateRng_Col, StoreCityRng_Col, StoreDateRng_Col, StoreNumRng_Col)
  rngVarColStr() = Array("StoreStateRng_Col", "StoreCityRng_Col", "StoreDateRng_Col", "StoreNumRng_Col")

  '获取从不包含空数据的已知范围:
  Set StoreNumRng = ws.Range(Cells(2, StoreNumRng_Col), Cells(2, StoreNumRng_Col))
  Dim i As Integer
  i = 0
  '获取已知数据集的完整范围以建立开始和结束行
  rw = StoreNumRng.Row '从上面删除的摘录中获取
  EndRw = StoreNumRng.End(xlDown).Row '从上面删除的摘录中获取
  
  For i = LBound(rngVars) To UBound(rngVars)
    If VarType(rngVars(i)) = vbObject Then
      Set rngVar = ws.Range(Cells(rw, rngVarCols(i)), Cells(EndRw, rngVarCols(i)))
      Set rngVars(i) = rngVar
      Debug.Print "变量" & rngVarStr(i) & "的地址 = " & rngVars(i).Address
    End If
  Next i
  Debug.Print StoreStateRng(1, 1).Value '失败,因为我假设这个变量没有设置。
End Sub

我尝试修改Variant.Name特性,它正确引用了SheetName$COL$ROW地址(甚至给我一个在工作表中跳转命名范围),而且Name.Name值与变量的名称匹配 - 但是Debug.Print StoreStareRng(1,1).Value失败,因为对象本身仍然为空。

我感觉离解决问题已经很接近了,但是对于我所缺少的东西感到困惑。

目标是拥有具名变量,以便在整个模块中引用。例如 - 我正在处理的数据集宽度超过20列,偏移大约20列,通常在10-30行之间。我希望避免的是对于Sheet的第23列的第3行的fullRange(3,6).Value的引用。Sheet的第23列将是指定范围的第6列)...

而是,我想引用StoreStateRng(3,1).Value来引用完全相同的范围,并使用实际工作表列的常量来修改这个范围的范围。如果将来范围的范围发生变化,我希望避免触及每个可能引用StoreStateRng的单个例程... 我还希望避免繁琐的操作:

Sub Get_Ranges()
  Set ws = ThisWorkbook.Sheets(wsNameMain)
  ws.Activate
  Set StoreStateRng = ws.Range(Cells(rw, StoreStateRng_Col),Cells(endRw, StoreStateRng_Col))
  Set StoreCityRng = ws.Range(Cells(rw, StoreCityRng_Col),Cells(endRw, StoreCityRng_Col))
  Set StoreDateRng = ws.Range(Cells(rw, StoreDateRng_Col),Cells(endRw, StoreDateRng_Col))
  Set StoreNumRng = ws.Range(Cells(rw, StoreNumRng_Col),Cells(endRw, StoreNumRng_Col))
  '重复,直到所有21个需要的范围都被填充
End Sub
英文:

Consider the Subroutine below. I almost have what I'm looking for, but it's not quite right.

Knowns to take into account: The Declarations statements for this Module have setup each variable (Totaling 63 - I've culled the majority to simplify the sample below) as Public Variables to be referenced at any time. I have done similar things with modifying Boolean Variable Values, but this is failing for some reason with Ranges and I think it has to do with the fact they are Objects.

The For Loop correctly pulls the relevant data and places it into the relevant placeholder within each Variant Array, meaning - the placeholder for StoreStateRng for example, holds the correct data frm the Ranges in the sheet, but when trying to manipulate the actual Range Variable stored inside the the placeholder, it fails to be referenced.

In theory - I would have expected this to physically set the Variable "StoreStateRng" to the range specified. . . It does indeed set rngVars(i) to the range specified, and gives it a Variant/Range Type when I inspect it on a Watch, but when inspecting the actual Variable at the same time, the Range Variable "StoreStateRng" is empty!

'Excerpt of Declarations Statement

'example of 3 of the 63 variables listed in the arrays below
Public Const StoreStateRng_Col As Integer = 23
Public StoreStateRng As Range
Public StoreStateRng_Val As Variant

'the Variant Arrays defined at the beginning of the sub
Public rngVar As Variant
Public rngVars() As Variant
Public rngVarStr() As Variant
Public rngVarCols() As Variant
Public rngVarColStr() As Variant
Public rngVarVals() As Variant
Public rngVarValStr() As Variant


Sub Get_Ranges()
  Set ws = ThisWorkbook.Sheets(wsNameMain)
  
  rngVars() = Array(StoreStateRng, StoreCityRng, StoreDateRng, StoreNumRng)
  rngVarStr() = Array("StoreStateRng", "StoreCityRng", "StoreDateRng", "StoreNumRng")
  rngVarCols() = Array(StoreStateRng_Col, StoreCityRng_Col, StoreDateRng_Col, StoreNumRng_Col)
  rngVarColStr() = Array("StoreStateRng_Col", "StoreCityRng_Col", "StoreDateRng_Col", "StoreNumRng_Col")

  'Get Known Range that never has blanks in data:
  Set StoreNumRng = ws.Range(Cells(2, StoreNumRng_Col), Cells(2, StoreNumRng_Col))
  Dim i As Integer
  i = 0
  'Get Full Range of Known data set to establish beginning and end rows
  rw = StoreNumRng.Row 'Pulled from the removed excerpt above
  EndRw = StoreNumRng.End(xlDown).Row 'Pulled from the removed excerpt above
  
  For i = LBound(rngVars) To UBound(rngVars)
    If VarType(rngVars(i)) = vbObject Then
      Set rngVar = ws.Range(Cells(rw, rngVarCols(i)), Cells(EndRw, rngVarCols(i)))
      Set rngVars(i) = rngVar
      Debug.Print "The Address for " & rngVarStr(i) & " = " & rngVars(i).Address
    End If
  Next i
  Debug.Print StoreStateRng(1, 1).Value 'Fails because I'm assuming this variable is not set.
  
  
End Sub

I did try modifying the .Name feature of the Variant's Placeholder and it references the SheetName$COL$ROW address properly (and even gives me a Named Range to Goto in the Sheet), and that Name.Name value matches the Name of the Variable - but the Debug.Print StoreStareRng(1,1).Value fails because the Object itself still is empty.

I feel like I'm really close to figuring it out, but having a hard time wrapping my head around what I'm missing.

The goal is to have named Variables with which to reference throughout the module. For example - the data set I'm working with is 20+ columns wide, offset roughly 20 columns from another existing set of data, and often between 10-30 rows deep. What I'm wanting to avoid is fullRange(3,6).Value for the 3rd row of the Sheet's Column 23. . . The Sheet's column 23 would be column 6 of the specified range). . . .

Instead, I would like to reference StoreStateRng(3,1).Value for this same exact range and use a Constant of the actual sheet's column to modify this should the scope of range change down the line vs trying to touch every single routine which may reference StoreStateRng . . .

I'm also hoping to avoid the cumbersome :

Sub Get_Ranges()
  Set ws = ThisWorkbook.Sheets(wsNameMain)
  ws.Activate
  Set StoreStateRng = ws.Range(Cells(rw, StoreStateRng_Col),Cells(endRw, StoreStateRng_Col))
  Set StoreCityRng = ws.Range(Cells(rw, StoreCityRng_Col),Cells(endRw, StoreCityRng_Col))
  Set StoreDateRng = ws.Range(Cells(rw, StoreDateRng_Col),Cells(endRw, StoreDateRng_Col))
  Set StoreNumRng = ws.Range(Cells(rw, StoreNumRng_Col),Cells(endRw, StoreNumRng_Col))
  'Repeat until all 21 needed ranges are populated
End Sub

答案1

得分: 2

When you do this

设置 rngVars(i) = rngVar

你正在用不同的变量替换原始的 Range 变量,而不是将原始的变量分配给 rngVar

更简单的版本:

子过程测试()

    Dim rngA As Range, rngB As Range, arrRanges As Variant
    
    arrRanges = Array(rngA, rngB)
    
    设置 arrRanges(0) = Range("A1:A5")  '这 *替换* 了 rngA...
    
    调试.打印 rngA.地址           '错误 - rngA 仍然是空的
    
结束 子过程

编辑 - 你的 "繁琐" 示例可以简化为相当易于维护的形式...

子过程设置范围()
    设置 ws = ThisWorkbook.Worksheets(wsNameMain)
    使用 ws.Range(ws.Cells(rw, "A"), ws.Cells(endRw, "A")).EntireRow
        设置 StoreStateRng = .Columns(StoreStateRng_Col)
        设置 StoreCityRng = .Columns(StoreCityRng_Col)
        设置 StoreDateRng = .Columns(StoreDateRng_Col)
        设置 StoreNumRng = .Columns(StoreNumRng_Col)
        '...
        '...
    结束 使用
结束 子过程
英文:

When you do this

Set rngVars(i) = rngVar 

you're replacing the original Range variable with a different one, not assigning the original one to rngVar

Simpler version:

Sub Tester()

    Dim rngA As Range, rngB As Range, arrRanges As Variant
    
    arrRanges = Array(rngA, rngB)
    
    Set arrRanges(0) = Range("A1:A5")  'This *replaces* rngA...
    
    Debug.Print rngA.Address           'Error - rngA is still Nothing
    
End Sub

EDIT - your "cumbersome" example could be streamlined to be quite maintainable...

Sub SetRanges()
    Set ws = ThisWorkbook.Worksheets(wsNameMain)
    With ws.Range(ws.Cells(rw, "A"), ws.Cells(endRw, "A")).EntireRow
        Set StoreStateRng = .Columns(StoreStateRng_Col)
        Set StoreCityRng = .Columns(StoreCityRng_Col)
        Set StoreDateRng = .Columns(StoreDateRng_Col)
        Set StoreNumRng = .Columns(StoreNumRng_Col)
        '...
        '...
    End With
End Sub

答案2

得分: 0

I'm sorry for the confusion, but it seems like you provided code snippets and descriptions related to a technical issue in programming. If you have any specific parts of this content that you would like me to translate into Chinese, please let me know, and I'll be happy to assist.

英文:

Finally implemented the method provided by Tim, and got a horrible 1004 - Application-error or Object-error when attempting to use this and access the ranges afterward. I'm ultimately keeping Tim's answer as the marked answer because he was right on merit even if his method caused me an unforseen error later on. Would love some insight on the nature of the phenomenon I show below (Object not defined error). . .

Using the following snippet:

Sub SetRanges()
    Set ws = ThisWorkbook.Worksheets(wsNameMain)
    With ws.Range(ws.Cells(rw, "A"), ws.Cells(endRw, "A")).EntireRow
        Set StoreStateRng = .Columns(StoreStateRng_Col)
        Set StoreCityRng = .Columns(StoreCityRng_Col)
        Set StoreDateRng = .Columns(StoreDateRng_Col)
        Set StoreNumRng = .Columns(StoreNumRng_Col)
        '...
        '...
    End With
    Debug.Print StoreNumRng(1, 1).Value 'Error 1004
End Sub

If I try to reference the value of a range using the rangeVar(row, col).value method, I received the 1004 error even though the Range Variables themselves are fully populated - I cannot understand the reason why it fails, so ultimately I did have to resort to using:

Sub Set_Ranges()
  Set ws = ThisWorkbook.Sheets(wsNameMain)
  ws.Activate
  Set StoreStateRng = ws.Range(Cells(rw, StoreStateRng_Col),Cells(endRw, StoreStateRng_Col))
  Set StoreCityRng = ws.Range(Cells(rw, StoreCityRng_Col),Cells(endRw, StoreCityRng_Col))
  Set StoreDateRng = ws.Range(Cells(rw, StoreDateRng_Col),Cells(endRw, StoreDateRng_Col))
  Set StoreNumRng = ws.Range(Cells(rw, StoreNumRng_Col),Cells(endRw, StoreNumRng_Col))
  'Repeat until all 21 needed ranges are populated
  Debug.Print StoreNumRng(1, 1).Value 'No Error and expected value prints.
End Sub

I believe a large portion of this is that for some reason, even though the Ranges are fully qualified as far as I can tell - when the error occurs and I debug, I get an Object not defined error here:

'Code code code
    Set StoreStateRng = .Columns 'Insert Error on `.Columns`(StoreStateRng_Col)
                                 'Note - All _Col values are correctly set.

使用包含范围变量的变体数组来填充后续通过变量名称引用的范围失败。

huangapple
  • 本文由 发表于 2023年5月11日 06:55:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76223074.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定