C #: ID-поле Microsoft.Office.Interop.Excel.Range не сохраняется в Excel-листе

Прежде чем я начну с проблемы, я хочу ее мотивировать. Моя задача - анализировать изменения в Excel-Sheet, но в отличие от записи изменений с помощью встроенного механизма, изменения должны обнаруживаться программно, и даже если пользователь отключил запись изменений или мой Excel-AddIn не установлен. Поэтому я использовал Microsoft.Interop. Библиотека Excel для доступа к листу и ячейкам внутри.

Теперь к проблеме: для поиска изменений, даже если пользователь отсортировал или переместил данные, я хотел иметь уникальный идентификатор для каждой ячейки, который прикрепляется к ней, даже если переместить или скопировать. Конечно, если скопировать, идентификатор будет дважды в листе, а новые добавленные ячейки не имеют идентификатора, но это нормально. Кроме того, этот идентификатор не должен быть виден пользователю, и пользователь не должен иметь возможность изменять или удалять его.

Итак, я поискал поле и нашел Range-Object , который может представлять собой одна ячейка и имеет разные элементы, к которым можно получить доступ. Одно специальное поле привлекло мое внимание, поле ID, которое выглядело как то, что я искал.

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

, а также читалось как

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

Это было идеально, потому что я мог хранить строку (в данном случае Guid как строка, например, 123463-fc34-c43a-a391-399fc2) и прочтите его. Он также прилип к ячейке и был перемещен, когда ячейка была перемещена и т. Д.

Но, к сожалению, это поле идентификатора не сохраняется, когда файл сохраняется, и я не знаю почему. Я имею в виду, что после закрытия и повторного открытия книги все идентификаторы исчезли.

Итак, мой вопрос в том, есть ли какой-либо другой член объекта Range, который может содержать строку (= Guid) и не виден пользователю. Я попробовал Name-Member и Comment-Member, но оба они видны пользователю и могут быть легко изменены.

Или есть способ сообщить Excel, что я тоже хочу сохранить поле ID , при сохранении листа?

Для тестирования вы можете создать проект, добавить ссылку на Microsoft.Office.Interop.Excel-Dll и добавить следующий код (в вашей системе должен быть установлен Excel). Это юнит-тест, Alex

Обновление 14.5.2011:

Поле «Имя» не является решением моей проблемы по следующим причинам:

Во-первых, и наиболее серьезным является тот факт, что кажется, что имя должно быть уникальный, но я хотел присвоить всем ячейкам подряд один и тот же идентификатор, что не работает.

Во-вторых, мне не совсем понятно, как получить доступ к полю имени в 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.Name, потому что первое поле Name - это не строка, а целый объект имени, внутри которого есть другое поле имени, которое содержит строку.

И, наконец, если вы хотите проверить, не есть имя или нет, вы не можете сделать что-то вроде:

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

, потому что он уже вызывает исключение при доступе к несуществующему полю имени.

6
задан Alexander Pacha 14 May 2011 в 20:22
поделиться