Поддержание COM-объекта Excel в живых - PullRequest
0 голосов
/ 07 апреля 2011

В настоящее время я использую механизм Excel 2003 Interop для управления некоторыми диапазонами .

Иногда я сохраняю некоторые диапазоны в своем дополнении , как свойства класса, но когда я пытаюсь получить к ним доступ в более позднее время, COM-объекты иногда случайным образом становятся недействительными, и каждое свойство COM-объектов выбрасывает« COMException », когда я пытаюсь получить к ним доступ.

Мне говорили, что нет сильной связи между объектами, которые Excel выделяет, и объектами, надстройкой которых являетсяиспользуя: так что "true" Объекты Range могут быть освобождены Excel в любое время, даже если с точки зрения .Net / C # у меня все еще есть ссылкаим.

Итак, мне было интересно, есть ли способ сохранить мои объекты Range, чтобы использовать их позже безопасным способом?

Примечание: я могиспользуйте обходной путь, такой как хранение строк , которые будут представлять диапазонов , eg «А1» вместо самих диапазонов , но это сделает код менее чистым.

Заранее спасибо за помощь.

1 Ответ

1 голос
/ 07 апреля 2011

Мне говорили, что нет сильной связи между объектами, выделяемыми Excel, и объектами, которые использует плагин

Это относится к тому факту, что Excel использует "Flyweights". Excel не использует COM внутри; он создает оболочки COM для своих внутренних структур (я считаю их «представлениями») по мере необходимости для обслуживания запросов COM-клиентом (будь то надстройка, VBA или внешнее приложение).

... "истинные" объекты Range могут быть освобождены Excel в любое время

Я бы не сказал «в любое время».

Как только вы получите объект Range или любой другой COM-объект, COM-объект будет оставаться доступным до освобождения (в смысле COM - вызов IUnknown::Release() для каждого AddRef()).

Однако , если вы удерживаете COM-объект и базовые структуры перестают существовать, COM-объект становится недействительным. Что еще это может сделать?

Допустим, вы держите Range, и пользователь удаляет лист, на котором находился диапазон. Как вы думаете, что должно произойти? Это не так, как Excel собирается выбросить окно с сообщением «извините, вы не можете удалить лист, потому что какой-то код хочет его удержать» . Если пользователь удалит данные, Excel будет соответствовать, и объект Range должен будет справиться. Ваша надстройка просто должна быть готова к такой возможности. Если надстройка предоставляет формулы, попросите их вернуть #REF и т. Д.

Я не думаю, что в любом случае можно заранее обнаружить это. Я проверил, есть ли где-нибудь метод IsValid (myRange), но я его не видел.

Во всяком случае, вряд ли это было бы очень полезно; Многие команды могут привести к тому, что сообщения [windows] будут обработаны, и в любое время, когда это происходит за пределами кода, он может выполняться в не подозревающее время и лишать вас диапазона. Вы действительно должны поймать ошибку, как она происходит, и правильно «выкинуть».

Может быть, вы правы. Это также может быть " в любое время ". Но это не случайно. Кто-то должен пойти и гадить с диапазоном.

Кстати, я бы не стал перехитрить ситуацию. Сохранение справочного текста диапазона приведет только к тому, что AddIn будет работать с другим набором данных, который предполагал пользователь. «Правильная» вещь - это «изящный провал».

...