Количество заполненных строк в SapTable

Я использую Silk4J, и у меня есть таблица, которая указана как SapTable в Locator Spy. Из этой таблицы я пытаюсь получить все тексты второго столбца, но он зависает или завершается с исключением. Ниже вы найдете код для моих попыток. Наконец я добрался до последней строки таблицы, но она снова зависла там.

Во всех примерах я использую цикл while вместо цикла for, потому что позже я хочу вставить дополнительные условия.

Попытка 1: Прямо вперед (я думал)

    SapTable table; // initialized somewhere else
    int maxrows = table.getRowCount();
    int row = 0;
    while (row < maxrows)
    {
        String text = table.getCell(row, COLUMN).getText();
        logger.debug(text);
        row++;
    }

Однако этот код печатает все видимые столбцы, а затем зависает.

Попробуйте 2: добавьте нажатие клавиши PageDn через Silk

Поскольку попытка 1 напечатала только видимые ячейки, я подумал, что может помочь добавление нажатия клавиши на каждой странице. Это был мой код:

SapTable table; // initialized somewhere else
int maxrows = table.getRowCount();
int row = 0;
int visibleRows = table.getVisibleRowCount();
table.setFocus();
while (row < maxrows)
{
    String text = table.getCell(row, COLUMN).getText();
    logger.debug(text);
    row++;
    if (row % visibleRows == 0)
        window.sendVKey(VKey.PAGE_DOWN);
}

К сожалению, это приводит к исключению «Виртуальный ключ не включен».

Попробуйте 3: добавьте нажатие клавиши PageDn через AwtRobot

Так как встроенный метод sendVKey не сработал, но нажатие PageDn вручную работает, я переключился на AwtRobot:

SapTable table; // initialized somewhere else
int maxrows = table.getRowCount();
int row = 0;
int visibleRows = table.getVisibleRowCount();
table.setFocus();
while (row < maxrows)
{
    String text = table.getCell(row, COLUMN).getText();
    logger.debug(text);
    row++;
    if (row % visibleRows == 0)
    {
        Robot robot = new Robot();
        robot.keyPress(KeyEvent.VK_PAGE_DOWN);
        robot.keyRelease(KeyEvent.VK_PAGE_DOWN);
    }
}

Нажатие клавиши теперь работает, и я вижу, как таблица прокручивается до следующей записи. Однако мое тестовое приложение все еще зависает.

Попробуйте 4: сброс количества строк

Снова используя Locator Spy, я обнаружил, что индекс строки сбрасывается до нуля, поэтому я имитировал это в своем коде:

SapTable table; // initialized somewhere else
int maxrows = table.getRowCount();
int row = 0;
int visibleRows = table.getVisibleRowCount();
table.setFocus();
while (row < maxrows)
{
    String text = table.getCell(row, COLUMN).getText();
    logger.debug(text);
    row++;
    if (row % visibleRows == 0)
    {
        Robot robot = new Robot();
        robot.keyPress(KeyEvent.VK_PAGE_DOWN);
        robot.keyRelease(KeyEvent.VK_PAGE_DOWN);
        row = 0; // <-- 
    }
}

В этом случае он печатает первые N (количество видимых) элементов списка, пролистывает до позиции N+1, печатает название первой (!) строки и затем зависает при обращении к элементу с индексом 1 (после сброса ).

Попытка 5: сон

Немного поспав, я могу дотянуться до конца стола:

SapTable table; // initialized somewhere else
int maxrows = table.getRowCount();
int row = 0;
int visibleRows = table.getVisibleRowCount();
table.setFocus();
while (row < maxrows)
{
    String text = table.getCell(row, COLUMN).getText();
    logger.debug(text);
    row++;
    if (row % visibleRows == 0)
    {
        Robot robot = new Robot();
        robot.keyPress(KeyEvent.VK_PAGE_DOWN);
        robot.keyRelease(KeyEvent.VK_PAGE_DOWN);
        row = 0;
        Thread.sleep(1000); // <--
    }
}

В этом случае я получаю все элементы в таблице. Но так как я не знаю, когда заканчивается таблица, она делает еще один вызов getCell(), что снова приводит к зависанию.

Вопрос

Я действительно застрял. Я также искал другие методы, такие как получение реального количества строк в таблице (getRowCount() нет), но пока не нашел.

Как получить реальное количество строк SapTable в Silk4J?


person Thomas Weller    schedule 09.02.2015    source источник


Ответы (1)


Потребовались некоторые попытки — базовый API автоматизации SAP в этом случае не очень полезен — но вот как вы можете заставить его работать:

private List<String> fetchItems() {
    SapTable table = desktop.find("sap.Table");
    SapVerticalScrollBar scrollBar = table.find("/SapVerticalScrollBar");

    // the scrollbar maximum value seems to be a more reliable
    // way to get the number of items than getRowCount
    int itemCount = scrollBar.getMaximum() + 1;

    List<String> items = new ArrayList<String>();
    int currentAbsoluteRow = 0;
    // the first loop iterates through the table page by page
    for (int firstRowInPage = 0; 
            firstRowInPage < itemCount; 
            firstRowInPage = scrollToNextPage(firstRowInPage)) {

        // this loop goes through the items of the current page
        for (int currentRowInPage = 0; 
                currentRowInPage < table.getVisibleRowCount(); 
                currentRowInPage++) {

            if(++currentAbsoluteRow > itemCount) {
                // we've read all the available items
                return items;
            }

            SapComponent cell = table.getCell(currentRowInPage, 1);
            items.add(cell.getProperty("Text").toString());
        }
    }
    return items;
}

private int scrollToNextPage(int firstRowInPage) {
    SapTable table = desktop.find("sap.Table");
    SapVerticalScrollBar scrollBar = table.find("/SapVerticalScrollBar");
    firstRowInPage += scrollBar.getPageSize();
    scrollBar.scrollTo(firstRowInPage);
    return firstRowInPage;
}

Некоторые подводные камни, с которыми я столкнулся:

  • getRowCount() вернул большее количество, чем было в реальных элементах
  • getVisibleRowCount() возвращает количество элементов, которые поместились бы на текущей странице, даже если не все строки были заполнены фактическими элементами.
  • Возвращаемые объекты ячейки действительны только до тех пор, пока ячейка находится на экране, поэтому вам нужно будет получить нужную информацию, прежде чем перейти к следующей странице.
person tehlexx    schedule 18.02.2015
comment
Это работает и для меня. Ради корректности (хотя он, вероятно, никогда не будет использовать начальный индекс, отличный от 0), я использую int itemCount = scrollBar.getMaximum() - scrollBar.getMinimum() + 1; вместо int itemCount = scrollBar.getMaximum() + 1; - person Thomas Weller; 18.02.2015
comment
Небольшим недостатком для меня было то, что в Locator Spy нельзя было выбрать вертикальную полосу прокрутки. При наличии таблицы относительный локатор "./SapVerticalScrollBar". (.VerticalScrollBar в приведенном выше коде — заданное имя элемента в карте объектов). - person Thomas Weller; 18.02.2015
comment
Да, извините за запись карты объектов - я должен был использовать локатор для этой цели. Я обновлю ответ. - person tehlexx; 19.02.2015