2

我在 C# 代码中从 NAmesManager 中删除名称时遇到了一些问题。根据我的要求,我需要从名称管理器中删除所有无效名称。我目前正在检查名称的值,如果值为“#REF!”,则将其删除。这是我正在使用的代码

foreach (Name RangeName in namesManager2)
                {

                    if(RangeName.Value.Contains("#REF!")) 
                    {
                        RangeName.Delete();
                    }
                 }

代码工作正常,但是有一些奇怪的情况存在 2 个名称相同但范围不同的名称。考虑单元格 1 被命名为“TESTNAME”,范围为“Workbook”,单元格 2 也被命名为“TESTNAME”,范围为“Sheet1”。引用 Cell2 的名称具有有效值。

因此,当我循环使用“#REF!”的名称时 遇到值上面的代码正在删除这两个名称。我想保留具有有效值的名称,但只删除无效的名称。

有人可以建议如何实现这一目标吗?

4

3 回答 3

1

存在重复的本地/全局名称的错误。
在活动工作表具有与该工作表相同的本地名称时访问全局名称,将更改本地名称的属性而不是全局名称,即使该名称与工作簿名称完全限定。

因此,要绕过这一点,您必须:
- 检测名称是否重复
- 如果是,则切换到不是本地名称父级的工作表(当然可能有多个本地名称,每张纸上一个,所以唯一真正安全的方法是添加另一个临时工作表并切换到该工作表)
- 然后在工作簿名称集合或工作表名称集合中访问您想要的任何名称。

这是 JK Pieterse 和我自己开发的免费 Name Manager Addin 使用的技术:
Name manager Download
,它比内置的 Name Manager 有更多的功能

于 2013-09-12T15:09:27.277 回答
0

我建议您为名称范围使用唯一名称以避免此类问题。

var activeBook = (Workbook)currentInstance.ActiveWorkbook;
Range rnArea = activeSheet.Range["A1:A1"];
activeBook.Names.Add("TESTNAME", rnArea);
rnArea = activeSheet.Range["B1:B1"];
activeSheet.Names.Add("TESTNAME", rnArea);

List<Name> existingNamedRangeList1 = XlHelper.GetNamedRanges(currentInstance.ActiveWorkbook);
foreach (Name RangeName in existingNamedRangeList1)
{
    if (RangeName.Value.Contains("#REF!"))
    {
        RangeName.Delete();
    }
}
于 2013-09-10T00:08:30.873 回答
0

不幸的是,它看起来假设名称是唯一的,因此任何删除操作都不会有预期的行为。解决此问题的一种方法是在遍历所有 RangeName 时生成一个唯一名称,然后在完成删除后将它们重置为原始名称。

var rangeNameHolder = new Dictionary<string, string>();
var rangeNames = activeBook.Names;
int counter = 0;
foreach (Name rangeName in rangeNames)
{
    var oldName = rangeName.Name;
    /*
     * This hack here is done because when you grab the name, it includes the prepended scope. 
     * However, when you set the name, it prepends the scope yet again! 
     * So when you grab it the first time you need to remove the scope so that it doesnt get
     * prepended twice
     */
    oldName =oldName.Substring(oldName.LastIndexOf('!')+1);
    var newName = string.Format("{0}{1}", oldName, counter++);
    rangeName.Name = newName;
    if (rangeName.Value.Contains("#REF!"))
    {
        rangeName.Delete();
        continue;
    }
    rangeNameHolder.Add(rangeName.Name,oldName);
}

//Reset names back to original
foreach (Name rangeName in rangeNames)
{
    if (rangeNameHolder.ContainsKey(rangeName.Name))
        rangeName.Name = rangeNameHolder[rangeName.Name];
}
于 2013-09-11T14:48:46.627 回答