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","")
式を検出するコード行は、上記の 2 つの場合は機能しません。
if (cellFormula.StartsWith("=") && cellFormula.Contains("!") && cellFormula.Contains("[") && cellFormula.Contains("]"))
私の質問は、私が認識していない構文が他にあり、ワークブック リンクのすべてのバリエーションを検出するためのエレガントなコードを推奨できる人はいますか?
私が見つけた別の製品はhttp://www.2haveit.com/listdetail.php?id=90005で、これは Excel アドインであるため、一度に 1 つのスプレッドシートでしか機能しませんが、それでも必要です私がやろうとしているように、そこにあるベースをカバーしました。
編集:Excelアドインではなく、winformアプリとしてこれが必要です
オブジェクト モデルにWorkbook.LinkSources Methodというメソッドがあることがわかりましたが、 このリンクも検出できません。
=Excel.Sheet.12|'C:\Temp\a.xlsx'!'!Sheet2!R6C3'