2011-05-13 3 views
6

과 함께 유지되지 않고 문제가 시작되기 전에 동기 부여하고 싶습니다. 내 작업은 Excel 시트의 변경 내용을 분석하는 것이지만 변경 내용을 프로그래밍 방식으로 검색해야하며 사용자가 변경 사항 기록을 비활성화했거나 Excel-AddIn이 설치되어 있지 않은 경우에도 변경 내용을 기록하는 것과 다릅니다. 그래서 Microsoft.Interop.Excel-Library를 사용하여 시트와 셀을 액세스했습니다.C# : Microsoft.Office.Interop.Excel.Range의 ID 필드가 Excel 시트

이제 문제가 생겼습니다 : 사용자가 데이터를 정렬하거나 이동 했더라도 이동하거나 복사하더라도 셀당 고유 ID를 보유하고 싶었습니다. 물론 복사되면 ID는 시트에서 두 번이고 새로 추가 된 셀에는 ID가 없지만 괜찮습니다. 이 ID는 사용자에게 보이지 않아야하며 사용자는 수정하거나 삭제할 수 없습니다.

그래서 필드를 찾아서 Range-Object이 발견되었습니다.이 셀은 단일 셀을 나타낼 수 있으며 액세스 할 수있는 다른 멤버가 있습니다. 하나의 특별한 분야가 제가 관심을 끌었습니다. ID 필드는 내가 찾고있는 것과 같습니다. 나는 123463-fc34-c43a-a391- 같은 문자열로 (이 경우 GUID를 문자열을 저장할 수 있었기 때문에 또한

Guid guid = Guid.NewGuid(); 
((Range) worksheet.Cells[rowNr, columnNr]).ID = guid.ToString(); 

Guid guid = Guid.Parse(((Range) worksheet.Cells[rowNr, columnNr]).ID); 

이 완벽처럼 읽을 수 399fc2)를 읽고 그것을 읽으십시오. 세포가 움직일 때도 세포에 붙어 움직였습니다.

불행히도이 ID 필드는 파일 저장시 저장되지 않으며 그 이유를 모르겠습니다. 통합 문서를 닫았다가 다시 열면 모든 ID가 사라졌습니다.

그래서 내 질문에 Range 개체의 다른 멤버가 있으면 문자열 (= Guid)을 보유 할 수 있으며 사용자에게는 보이지 않습니다. 나는 Name-Member와 Comment-Member를 시도했지만, 둘 다 사용자에게 보이고 쉽게 수정할 수 있습니다.

시트를 저장할 때 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를 부여하고 싶습니다. 작동하지 않습니다.

둘째, 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-Object인데, 내부에는 문자열을 포함하는 다른 Name-Field가 있기 때문에 Name.Name이 필요합니다.

그리고 당신이 이름이 아닌지 확인하려는 경우 마지막으로, 당신이 할 수없는 무언가와 같은 :

if(((Range)worksheet.Cells[rowNr, columnNr]).Name == null) 
    //Do something 

존재하지 않는 이름 필드에 액세스 할 때 이미 예외가 발생하기 때문이다.

답변

1

실제로 ID를 시트에 그대로 유지할 방법이 없습니다. ID 필드 (유지되지 않음) 또는 이름 (고유 한 이름 만 허용됨) 또는 주석 (사용자에게 표시됨)이 아닙니다.

그러나 문자열을 저장할 수있는 통합 문서에는 개념이 있으며 모든 직렬화 가능 클래스를 문자열로 정렬 할 수 있으므로 프로그래머는 통합 문서를로드 할 때 ID를 별도로 유지하고 복원 할 수 있습니다.

어쨌든 다른 목적으로는 각 행의 해시 값을 계산하고 대신 행 해시 값을 비교합니다.

1

각 셀에 명명 된 범위를 사용해 볼 수 있습니다. 이름은 계속됩니다. 나는 interop과 함께 이것을 시도하지 않았지만 좋은 오래된 vba와 함께 작동합니다. 아래 코드에서 사용자의 이름을 숨길 수 있습니다. 내가 통합 문서의 명명 된 범위의 수에는 논리적 limit이없는 이해 것과

Function try() 
    Dim x As Integer 
    Dim y As String 

    Worksheets("Sheet1").Range("a1").Name = "_firstCell" 
    Range("_firstCell").Value = 9999 
    Dim nm As Name 
    'hide 
    For Each nm In ActiveWorkbook.Names 
     If Left(nm.Name, 1) = "_" Then 
      nm.Visible = False 
     End If 
    Next 
    'move the named cell 
    Range("_firstCell").Cut Range("b1") 
    'check the value and address 
    x = Range("_firstCell").Value 
    y = Range("_firstCell").Address 

End Function 

.

0

하여 사용해보십시오 : FormatConditions activecell.FormatConditions.Add xlExpression을, formula1을 = "test_1234" 을

ID IDRange = 중간 (activecell.FormatConditions (1) .formula1,2) "test_1234"에 대한 값을 얻기 위해