に保存されていません。動機付けたいと思います。私の仕事は、Excelシートの変更を分析することですが、変更をプログラムで検出する必要があります。また、ユーザーが変更の記録を無効にした場合や、Excel-AddInがインストールされていない場合もあります。そこでMicrosoft.Interop.Excel-Libraryを使用して、シートとその中のセルにアクセスしました。C#:Microsoft.Office.Interop.Excel.RangeのIDフィールドは、問題が始まる前にExcelシート
変更点:ユーザーがデータをソートまたは移動した場合でも、移動またはコピーしても、セルごとにユニークIDを保持したいと思っていました。もちろんコピーした場合、IDはシート内で2回あり、新しい追加セルにはIDはありませんが、それは問題ありません。さらに、このIDはユーザーに表示されるべきではなく、ユーザーはそれを変更または削除できないようにすべきです。
フィールドを探して、Range-Objectが見つかりました。これは単一のセルを表すことができ、アクセス可能なメンバーが異なります。 1つの特別なフィールドが私の注意を引いた.IDフィールドは、私が探していたもののように見えた。
Guid guid = Guid.NewGuid();
((Range) worksheet.Cells[rowNr, columnNr]).ID = guid.ToString();
とも123463-fc34-c43a-a391-よう
Guid guid = Guid.Parse(((Range) worksheet.Cells[rowNr, columnNr]).ID);
私は文字列として、この場合のGUIDで(文字列を格納することができたので、これは、完璧だった、のように読み取ることが399fc2)を読み、それを読んでください。また、セルに移動して移動したときに移動しました。
残念ながら、このIDフィールドはファイルが保存されても保持されません。その理由はわかりません。ワークブックを閉じて再オープンした後、すべてのIDがなくなったということです。
だから私の質問は、文字列(= Guid)を保持することができ、ユーザーが見ることができないRangeオブジェクトの他のメンバーがある場合です。私は名前 - メンバーとコメント - メンバーを試しましたが、どちらもユーザーに見え、簡単に変更できます。
また、シートを保存するときに、IDフィールドも保存することをExcelに伝える方法はありますか?
テスト用に、プロジェクトを作成し、Microsoft.Office.Interop.Excel-Dllへの参照を追加し、次のコードを追加します(システムにExcelがインストールされている必要があります)。これは、JUnitので実行ユニットテスト、ですが、あまりにもJUnitをせずに、それをテストするためにアサート-コマンドを削除します。
using System;
using System.IO;
using Microsoft.Office.Interop.Excel;
using Excel = Microsoft.Office.Interop.Excel;
public void AddGuidAndRead()
{
Excel.Application excelApp = new Excel.Application();
Workbook excelWorkbook = excelApp.Workbooks.Add(Type.Missing);
Worksheet worksheet = excelWorkbook.Sheets[1]; //1-based index
Guid rowGuid1 = Guid.NewGuid();
const string filename = "C:\\temp\\anyTemporaryFilename.xlsx";
//Make sure, this file does not exist previously
if (File.Exists(filename))
File.Delete(filename);
//Write the ID to the worksheet
((Range)worksheet.Cells[1, 1]).ID = rowGuid1.ToString();
//Act (save and close the workbook)
excelWorkbook.SaveAs(filename);
excelWorkbook.Close();
//Now open the workbook again
Workbook openedWorkbook = excelApp.Workbooks.Open(filename);
//Fetch the worksheet, where we worked previously
Worksheet openedWorksheet = openedWorkbook.Sheets[1]; //1-based index
//Read the ID from the cell
string guid1 = ((Range)openedWorksheet.Cells[1, 1]).ID;
//Cleanup
openedWorkbook.Close(false);
File.Delete(filename);
excelWorkbook.Close(false, Type.Missing, Type.Missing);
excelApp.Quit();
//Assert - this fails!!
Assert.AreEqual(rowGuid1.ToString(), guid1);
}
私はエクセル-Worksheet-にIDを入れてどのように任意のアイデアを、感謝しますワークシートなどを保存するときに保持されるセル。
事前に多くのおかげで、 アレックス
アップデート2011年5月14日:
名フィールドには、次のような理由のために私の問題への解決策ではないように思わ:
まず、最も深刻なのは、名前が一意でなければならないという事実ですが、行内のすべてのセルに同じIDを与えたいと思っています。これはうまくいきません。
第2に、Cの名前フィールドにアクセスするには、私には本当に明確ではありません。
((Range)worksheet.Cells[rowNr, columnNr]).Name = guid.ToString();
//Remark: Special dealing with guids required,
//if they start with a number or contain special characters.
で値を設定できますが、重大な問題があります。名前が既に設定されている場合は、名前が設定されていない場合に例外がスローされ、アクセスしようとします。
string name = ((Range)worksheet.Cells[rowNr, columnNr]).Name.Name;
例外があります。最初のName-fieldは文字列ではなく、文字列を含む別のName-Fieldを持つName-Object全体であるため、Name.Nameが必要です。
そして、あなたはそれが名前を持っているかいないかどうかを確認したい場合は、最終的に、あなたが行うことができない何かのように:
if(((Range)worksheet.Cells[rowNr, columnNr]).Name == null)
//Do something
存在しない名前フィールドにアクセスするとき、それはすでに例外がスローされますので。