Неверный счет C# UsedRange

Я использовал свойство UsedRange объекта Excel.Worksheet, чтобы получить количество строк и столбцов. Если я попытаюсь удалить столбец или строку, количество UsedRange должно уменьшиться соответственно. Однако после долгих отладок в определенном порядке изменилось свойство Hidden и ширина столбца столбца. Счетчик не изменится соответственно, что должно означать, что для ячейки установлен якорь. Пожалуйста, помогите объяснить (поскольку это сильно влияет на мои коды).

Тестовые коды:

Worksheet worksheet = Globals.ThisAddIn.Application.ActiveSheet;
Debug.WriteLine("Used Range Column Count 1: " + worksheet.UsedRange.Columns.Count);

worksheet.Range["A1"].Formula = "1";
worksheet.Range["B1"].Formula = "1";
worksheet.Range["C1"].Formula = "1";
worksheet.Range["D1"].Formula = "1";
Debug.WriteLine("Used Range Column Count 2: " + worksheet.UsedRange.Columns.Count);

Range column = worksheet.Columns[4];
column.Delete();
Debug.WriteLine("Used Range Column Count 3: " + worksheet.UsedRange.Columns.Count);

worksheet.Range["D1"].Formula = "1";
column = worksheet.Columns[4];
column.ColumnWidth = 20.0;
column.Hidden = true;
column.Hidden = false;
column.Delete();
Debug.WriteLine("Used Range Column Count 4: " + worksheet.UsedRange.Columns.Count);

worksheet.Range["D1"].Formula = "1";
column = worksheet.Columns[4];
column.Hidden = true;
column.Hidden = false;
column.ColumnWidth = 20.0;
column.Delete();
Debug.WriteLine("Used Range Column Count 5: " + worksheet.UsedRange.Columns.Count);

Результаты:

Количество используемых столбцов диапазона 1: 1 (ожидается)
Количество используемых столбцов диапазона 2: 4 (ожидается)
Количество используемых столбцов диапазона 3: 3 (ожидается)
Количество используемых столбцов диапазона 4: 4 (не ожидается)
Число используемых столбцов диапазона 5: 3 (ожидается)


Дальнейшие описания необходимости правильного подсчета используемых диапазонов:

Я работаю над приложением, которое может улучшить интерфейс Excel. Например, у пользователя есть список запасов и стоимость покупки с промежуточной суммой или строкой средней цены в конце. (фактическая строка промежуточного итога будет намного сложнее, чем сумма и среднее значение). Поэтому список должен быть расширяемым, а строка промежуточного итога — нет. В результате мне нужно отслеживать, добавляется или удаляется новая строка или новый столбец, поэтому мне нужно перепроверить количество на листе Excel с историческим (кешированным) количеством. Поскольку новая строка или столбец могут не содержать фактических данных, я использовал свойство UsedRange, чтобы определить отображаемое текущее количество строк/столбцов. Следовательно, тот факт, что UsedRange включает удаленные строки/столбцы, делает мой расчет невозможным.


Хотя я не могу найти способ снять эффект якоря, я, наконец, нашел способ сделать эту работу:

Использование диапазона имен одной ячейки для обозначения последней ячейки рабочего листа со свойством UsedRange для инициализации диапазона.

Если вам нужно не показывать пользователям диапазон, вы можете попробовать сохранить данные в настраиваемых свойствах на листе. Однако этот подход потребует гораздо большего внимания к отслеживанию действий пользователя (ссылка на именованный диапазон автоматически изменится, если вы добавите строку/столбец).


person Carson    schedule 14.01.2017    source источник
comment
Я преобразовал ваш код в VBA и запустил его. Это дало те же результаты. Я думаю, это как-то связано с таинственным способом работы объекта UsedRange. За последние несколько дней я прочитал несколько сообщений и все еще пытаюсь понять, как это работает.   -  person vknowles    schedule 14.01.2017
comment
Да, очень расстроился. Я могу понять, что им нужен определенный способ установки привязки, чтобы определить, какая ячейка используется последней, но они должны предоставить способ удалить привязку.   -  person Carson    schedule 15.01.2017
comment
Я не думаю, что они делают это намеренно, это больше похоже на очередную ошибку Excel, когда триггер скрывает диапазон, ширина которого была изменена. Даже сохранение файла не помогает.   -  person GSerg    schedule 15.01.2017


Ответы (1)


Ну, UsedRange не подходит для определения последней строки и столбца. Вместо этого вы можете использовать этот код:

// get last row
var WorksheetLastRow = worksheet.Cells.Find(
    What: "*",
    SearchOrder: Excel.XlSearchOrder.xlByRows,
    SearchDirection: Excel.XlSearchDirection.xlPrevious,
    MatchCase: false
).Row;

// get last column
var WorksheetLastCol = worksheet.Cells.Find(
    What: "*",
    SearchOrder: Excel.XlSearchOrder.xlByColumns,
    SearchDirection: Excel.XlSearchDirection.xlPrevious,
    MatchCase: false
).Column;
person Xaver    schedule 14.01.2017
comment
Я широко использовал UsedRange в своих кодах... Я согласен с использованием UsedRange для получения любого количества строк, если его можно удалить... Итак, нет идей по этому поводу? - person Carson; 15.01.2017
comment
Я только что попробовал этот метод, но он не может захватывать отформатированные ячейки, есть еще идеи? - person Carson; 15.01.2017
comment
Проблема с ложными результатами для UsedRange возникает не только с VSTO, но и при непосредственном использовании Excel: представьте, что у вас есть рабочий лист, например, с 8 рядов и 2 столбца. При нажатии Ctrl+End на клавиатуре должна быть выбрана последняя ячейка (т.е. ячейка, которая находится в последней строке и в последнем столбце). Это работает, вы получаете ячейку в строке 8, столбце 2. Но если вы удалите одну из 8 строк, вы можете себе представить, что при нажатии Ctrl+End вы получите строку 7, столбец 2. Но это не работает, вы все равно получаете строку 8, столбец 2. - person Xaver; 16.01.2017
comment
Что касается вашей проблемы с форматированными ячейками: можете ли вы описать свою проблему более подробно? Я был бы рад помочь, но я не уверен, в чем именно проблема. - person Xaver; 16.01.2017
comment
Проблема, которую вы предоставили, является препятствием для моего приложения. Я нашел способ (обновлено в вопросе), чтобы временно получить нужный мне результат, но это связано с некоторыми проблемами. Пожалуйста, совет, если у вас есть еще идеи. - person Carson; 17.01.2017