http://www.linkfixerplus.com有一个产品来检查工作簿链接并修复它们,但它很昂贵,我被要求编写一个只检查交叉引用(工作簿链接)而不担心它们是否损坏的产品.
这是到目前为止我编写的基本代码(在这个阶段更像是伪代码 - 目标是 .Net 2 所以忘记 LINQ):
public class LinkInfo
{
public string SheetName { get; set; }
public string Cell { get; set; }
public string CellValue { get; set; }
}
private bool ExcelFileHasLinks(string path,ref List<LinkInfo> linkInfoList)
{
bool hasLinks = false;
Workbook wb = null;
try
{
wb = excel.Workbooks.Open(path);
foreach (object possibleSheet in excel.Sheets)
{
var aSheet = possibleSheet as Worksheet;
if (aSheet != null)
{
//Get the values in the sheet
Range rng = aSheet.UsedRange;
object[,] values = null;
try
{
if (rng.Value2.GetType().IsArray)
{
values = (object[,])rng.FormulaArray;
}
else
{
values = new object[2, 2];
values[1, 1] = rng.FormulaArray;
}
}
catch
{ }
if (values != null)
{
for (int row = 1; row <= values.GetUpperBound(0); row++)
{
for (int col = 1; col <= values.GetUpperBound(1); col++)
{
if (values[row, col] != null)
{
//Check if this iis a link to another workbook
string cellFormula = values[row, col].ToString().Trim();
if (cellFormula.StartsWith("=") && cellFormula.Contains("!") && cellFormula.Contains("[") && cellFormula.Contains("]"))
{
hasLinks = true;
linkInfoList.Add(new LinkInfo() { SheetName = aSheet.Name, Cell = ColumnNumberToName(col) + row, CellValue = cellFormula });
}
}
}
}
}
}
}
}
catch (Exception)
{
}
finally
{
if (wb != null) wb.Close();
}
return hasLinks;
}
当 XLS 文件具有以这种方式表示的其他工作簿的链接时,这非常有效:
=[a.xlsx]Sheet1!$A$1
我的问题是 SAN 中确实有数十万个电子表格,由于敏感,我不允许查看它们!所以我进行了测试,看看是否有各种语法可以做到这一点,我发现了这个:
=Excel.Sheet.12|'C:\Temp\a.xlsx'!'!Sheet2!R6C3'
还有这个:
=EMBED("Excel.Sheet.12","")
检测公式的代码行不适用于上述两个:
if (cellFormula.StartsWith("=") && cellFormula.Contains("!") && cellFormula.Contains("[") && cellFormula.Contains("]"))
我的问题是还有更多我不知道的语法,任何人都可以推荐优雅的代码来检测工作簿链接的所有变体吗?
我发现可以做到的另一种产品是http://www.2haveit.com/listdetail.php?id=90005它是一个 Excel 插件,所以它一次只能在一个电子表格上工作 - 但他们仍然必须有正如我正在尝试做的那样,覆盖了那里的基地。
编辑:我需要这个作为一个 winform 应用程序而不是 Excel 加载项
我发现对象模型中有一个方法: Workbook.LinkSources Method但是它也无法检测到此链接:
=Excel.Sheet.12|'C:\Temp\a.xlsx'!'!Sheet2!R6C3'