Excel VBA命名范围在引用空间不足

因此,我有一大套代码可以在员工使用的工作表中创build数据存档。 使这个function的一部分被命名为每个可用数据表的范围。 为了保持数据的完整性,我需要将命名的范围对象从归档表复制到它的副本。 指定的范围以编程方式构build,并在纸张上按预期方式运行。 我遇到的问题是当我去归档表单。 这里是我用来处理命名的范围对象的代码:

For Each n In OldSht.Names NamedRangeRefersTo = n.RefersTo NamedRange = n.Name TrimmedName = Right(n.Name, Len(n.Name) - InStr(1, n.Name, "!", vbTextCompare)) OldSht.Names(n.Name).Delete OldSht.Names.Add Name:=ArchiveNamedRange, RefersTo:=NamedRangeRefersTo Next n 

从n获取数据的string用于将相同的名称对象添加到新工作表。

我遇到的问题是,当一个命名的范围引用了Oldsht.Names.Add这行时,它引用的范围太大,它返回错误1004.我想通过乱搞它是参考范围的大小。 我没有find确切的触发原因,但是当我在大多数命名的范围上使用它时,这个代码是按原样工作的。 在具有连接数据types的大型数据集上导致一个非常大的命名范围(需要很长时间来解释范围是如何构build在文本中的,这是一组包含2000多行代码的8个子function)导致1004错误。

我感到困惑的是为什么我可以build立命名的范围,使用命名的范围,并复制命名的范围没有问题(如果我注释掉违规行,它执行完美,但我失去了数据完整性)。 但是,当我将引用的范围转换为代码值时,请删除旧的名称引用,然后添加一个新的名称(使用不同的名称),并为它指定与旧名称相同的引用值,则可能会出现此问题。 我不明白这样做会有什么不同,而不是复制/重命名名称对象。 不幸的是,我还没有find解决方法,除了在testing场景中删除数据或使用更小的数据集时,我也没有发现导致此错误的明确原因。 有没有人有我能做什么的想法? 有没有人有任何想法如何命名范围可以指足够小的范围,它可以创build,但使用其引用值来创build一个新的命名范围可能会导致错误,只有当它是引用一个大范围?

我希望我能提供一些更具体的例子,但不幸的是,擦洗足够的敏感信息是非常困难的,以提供完整的代码来重现我的确切情况。 任何想法将不胜感激。

按照这里的要求设置ArchiveNamedRange:

 If Len(OldSht.Name) > 21 Then ArchiveShtName = Left(OldSht.Name, 21) & DatePart("m", Date) & DatePart("d", Date) & DatePart("yyyy", Date) Else ArchiveShtName = OldSht.Name & DatePart("m", Date) & DatePart("d", Date) & DatePart("yyyy", Date) End If ArchiveNamedRange = ArchiveShtName & NameObjectName & "Test" 

NameObjectName只是对象types的名称,并从另一个函数传入。 我没有问题,只是fyi的名字。 在最极端的例子中,debugging运行时的ArchiveNamedRange值是=“OutageSystemProcedureMMDDYYYYSecurityRedactionTest”,所以名字可能会达到50,如果事情变得更疯狂,它可能会运行60个字符,但不会超过255或255字符限制。 最终,我还没有看到ArchiveNamedRange有一个无效的值。 这只是一个string,它总是有价值的。

编辑 – 通过我的故障排除,我发现我的代码在NamedRangeRefersTo的长度为2075时工作,但在长度为2091时不起作用。因此,在2075个字符和2091个字符之间的地方是将string分配给指的是:在一个命名的范围内。

所以,让我们假设2080年(或者2075年和2091年之间的任何事实)有一个字符限制。 当我最初find并创build这些命名的范围,他们正在给一个范围对象。 当我复制作为string复制的范围。 不知何故,当我将一个远程对象传递给RefersTo时:它接受2080以后的字符,但是当我传入一个string时,它不会。 鉴于这是我大量代码中唯一的突破点,我宁愿为此寻找解决方法,而不得不重新考虑我的归档系统的整个概念。 如果我使用范围对象来复制命名的范围,则它们的引用将跟随旧的表单。 这意味着当我复制名称时,它可以是“CriticalSystemsTest1”,并参考:“CriticalSystemsTest1!$ A $ 2,…”但是一旦我复制并重命名归档工作表(现在CriticalSystems562015)引用调整为“ CriticalSystems562015Test1!$ A $ 2,…”

所以我不得不复制为一个string,以避免这个问题(它破坏了新的工作表上的数据)。 所有我真正需要的是一个创造性的方式来克服我的string这个字符限制问题。 在新工作表上从头开始重新命名的范围也不起作用。 所以我想如果有人有如何解决这个string大小的问题或修改string的方法,同时保持命名范围的function的想法,这将是惊人的。

这些名称中的每一个都有一个工作表级别的范围,所以也许如果有一种方法只使用RefersTo中的单元格地址($ A $ 2):所以它不包含工作表引用(SheetName!),这将是一个潜在的解决scheme,但我还没有想出如果这是可能的。

作为string的范围定义如此之长的原因在于它们中有许多区域。 所以一个解决方法是按区域build立一个新的Range对象区域。 您可以使用每个区域的string地址,而不会受到任何限制,因为每个区域只有一个简短的引用。 使用Range.Address获取没有工作表引用的单元格引用,因此您可以在不同工作表上创build一个新的Range ,但使用相同的单元格。 然后使用Union()join所有区域,并使用新build的Range而不是string创build新名称:

  Dim i As Long, oldRange As Range, newRange As Range Set oldRange = n.RefersToRange Set newRange = oldSht.Range(oldRange.Areas(1).Address(External:=False)) For i = 2 To oldRange.Areas.Count Set newRange = Union(newRange, oldSht.Range(oldRange.Areas(i).Address(External:=False))) Next i oldSht.Names.Add Name:="ArchiveNamedRange", RefersTo:=newRange 

几个注意事项:

对于许多领域的范围这是缓慢的 。 如果您可以可靠地限制出现问题的门槛,则可能首先需要进行testing,并仅在需要时使用此解决方法。

在testing时,我也遇到了使用Worksheet.Range("some very long string range reference") ,所以这个限制不局限于命名范围。