Как перебрать все разрывы страниц на листе Excel 2003 через COM

Я пытался получить расположение всех разрывов страниц на данном листе Excel 2003 через COM. Вот пример того, что я пытаюсь сделать:

Excel::HPageBreaksPtr pHPageBreaks = pSheet->GetHPageBreaks();
long count = pHPageBreaks->Count;
for (long i=0; i < count; ++i)
{
  Excel::HPageBreakPtr pHPageBreak = pHPageBreaks->GetItem(i+1); 
  Excel::RangePtr pLocation = pHPageBreak->GetLocation();

  printf("Page break at row %d\n", pLocation->Row);

  pLocation.Release();
  pHPageBreak.Release();
}
pHPageBreaks.Release();

Я ожидаю, что это распечатает номера строк каждого из горизонтальных разрывов страниц в pSheet. Проблема, с которой я столкнулся, заключается в том, что, хотя count правильно указывает количество разрывов страниц на листе, я могу получить только первый из них. При втором прогоне цикла вызов pHPageBreaks->GetItem(i) вызывает исключение с номером ошибки 0x8002000b, "недопустимый индекс".

Попытка использовать pHPageBreaks->Get_NewEnum(), чтобы заставить перечислитель перебирать коллекцию, также завершается с той же ошибкой сразу при вызове Get_NewEnum().

Я искал решение, и самое близкое, что я нашел, это http://support.microsoft.com/kb/210663/en-us. Я пробовал активировать различные ячейки за пределами разрывов страниц, в том числе ячейки, находящиеся сразу за пределами диапазона для печати, а также нижнюю правую ячейку (IV65536), но это не помогло.

Если кто-нибудь может сказать мне, как заставить Excel возвращать расположение всех разрывов страниц на листе, это было бы здорово!

Спасибо.

@Joel: Да, я пытался отобразить пользовательский интерфейс, а затем установить для ScreenUpdating значение true - это дало те же результаты. Кроме того, с тех пор я пробовал комбинации установки pSheet->PrintArea для всего рабочего листа и/или вызова pSheet->ResetAllPageBreaks() перед моим вызовом для получения коллекции HPageBreaks, что также не помогло.

@Joel: я использовал pSheet->UsedRange, чтобы определить строку для прокрутки, и Excel действительно прокручивает все горизонтальные разрывы, но у меня все еще возникает та же проблема, когда я пытаюсь получить доступ ко второй. К сожалению, переход на Excel 2007 тоже не помог.


person Martin    schedule 16.09.2008    source источник


Ответы (2)


Экспериментируя с Excel 2007 из Visual Basic, я обнаружил, что разрыв страницы неизвестен, если он не отображается на экране хотя бы один раз.

Лучшим обходным решением, которое я смог найти, было прокрутить страницу вниз, от верхней части листа до последней строки, содержащей данные. Затем вы можете перечислить все разрывы страниц.

Вот код VBA... дайте мне знать, если у вас возникнут проблемы с преобразованием этого в COM:

Range("A1").Select
numRows = Range("A1").End(xlDown).Row

While ActiveWindow.ScrollRow < numRows
    ActiveWindow.LargeScroll Down:=1
Wend

For Each x In ActiveSheet.HPageBreaks
    Debug.Print x.Location.Row
Next

Этот код сделал одно упрощающее предположение:

  • Я использовал метод .End(xlDown), чтобы выяснить, как далеко идут данные... это предполагает, что у вас есть непрерывные данные от A1 до нижней части листа. Если вы этого не сделаете, вам нужно использовать какой-то другой метод, чтобы выяснить, как далеко продолжать прокрутку.
person Joel Spolsky    schedule 17.09.2008
comment
В дополнение к этому я обнаружил, что для Application.ActiveWindow.View необходимо установить значение xlNormalView (а не xlPageBreakPreview). Я все еще получаю ту же ошибку 8002000b, если только у меня не установлено представление xlNormalView. Спасибо за помощь! - person Martin; 18.09.2008

Вы установили для параметра ScreenUpdating значение True, как указано в статье базы знаний?

Возможно, вы захотите переключить его на True, чтобы принудительно перерисовать экран. Похоже, что расчет разрывов страниц является побочным эффектом фактического рендеринга страницы, а не тем, что Excel делает по запросу, поэтому вам нужно инициировать рендеринг страницы на экране.

person Joel Spolsky    schedule 17.09.2008