http://www.linkfixerplus.com have a product to check workbook links and fix them, but its expensive and I've been asked to write one that will just check for Cross References (workbook links) and not worry if they are broken.
This is the bare bone code I've written so far (more like psuedo code at this stage - targeting .Net 2 so forget 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;
}
This works perfectly when the XLS files have links to other workbooks expressed this way:
=[a.xlsx]Sheet1!$A$1
My problem is that there are literally hundreds of thousands of spreadsheets in the SAN and I am not allowed to view them due to sensitivity! So I was conducting tests to see if there are various syntaxes to do it and I found this:
=Excel.Sheet.12|'C:\Temp\a.xlsx'!'!Sheet2!R6C3'
and this:
=EMBED("Excel.Sheet.12","")
The line of code detecting the formula isn't going to work for the above two:
if (cellFormula.StartsWith("=") && cellFormula.Contains("!") && cellFormula.Contains("[") && cellFormula.Contains("]"))
My question is there any more syntaxs that I am not aware of and can anyone recommend elegant code to detect all the variations of workbook links?
The other product I found that can do it is http://www.2haveit.com/listdetail.php?id=90005 and its an Excel Add-In so it only works on one spreadsheet at a time - but they still must have covered there bases as I'm trying to do.
Edit: I need this as a winform app not Excel Add-In
I found out there is a method in the object model: Workbook.LinkSources Method however it fails to detect this link as well:
=Excel.Sheet.12|'C:\Temp\a.xlsx'!'!Sheet2!R6C3'