Вопрос про активность "Прокрутить"

addewyd@

Member
Имеется датагрид с неизвестным (достаточно большим) количеством строк. Необходимо прокрутить грид с начала до конца так, чтобы не пропустить ни одну строку. А в активность можно передавать только целое количество процентов.
Или я не могу сообразить, как это сделать, или не хватает опции "прокрутить на одну строку" и out параметра, сообщающего о конце прокрутки.
Можно было бы найти картинку "стрелка" на скроллбаре и в цикле кликать, но 1) ненадёжно, 2) всё равно нет условия выхода из цикла.

Что посоветуете?

UPD
Про целое число процентов снимается (если вызывать напрямую UIElement.Scroll.

Но условия завершения нет. Было бы неплохо иметь bool Scroll() для этой цели...

УПД2

Кое как справился со скроллами в своей задаче, создав активность с вызовом GetScrollInfo (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getscrollinfo). Пока этого достаточно, УИ сделан на QT.

Но...
Вот тут уже не работает даже стандартное "Прокрутить":


1612331114540.png
/Window[@ClassName = 'Window' and @Name = 'PIX Studio']/Custom[@AutomationId = 'root' and @ClassName = 'ProjectScreen']/Tab[@ClassName = 'TabControl']

С прочими (WPF и не только) тоже не работает.
 
Последнее редактирование:

addewyd@

Member
Кому интересно, нарисовалась активность "Получить позицию скролла" Берём разность, и двигаем приблизительно на эту величину куда надо. Учтя некоторые тонкости. Не удалось с WPF. С QT5 работает.

Собственно, там всего 3 строчки
C#:
        public override void Execute(int? optionID)
        {
            var Rect = Element.GetRectangle();
            var hwnd = Desktop.Core.Win32.WindowFromPoint(Rect.Location);
            ScrollPos =  GetScrollPos(hwnd, SB_VERT);
            if(ScrollPos == 0)
            {
                Error = Marshal.GetLastWin32Error();
            }
        }
 
Последнее редактирование:

addewyd@

Member
И всё-таки, что-то не складывается. Наверное, я не силён в арифметике.
Кто-нибудь подскажет, на какое количество процентов следует прокрутить датагрид, чтобы он сместился на ровно на одну строку?
Вычисляем количество строк
nlines = scrollinfo.nMax - scrollinfo.nMin
проценты на строку
double pcd = 100.0 / nLines

element.Scroll(Down, pc) иногда двигается, иногда нет. Чаще нет

int pci = Ceiling(pcd) // Round, Floor...

"Прокрутить на pci %" тут зависит от значения pcd и способа округления....

А надо бы точно.

Собственно, есть окно с таблицей. Таблица с произвольным количеством строк, заранее неизвестным. Надо жамкнуть мышкой в каждую строку. Пропускать строки нельзя. Повторять клик на ту же строку тоже нельзя. Категорически.

Можно, конечно, что-нибудь такое изобразить Ceiling(100.0 / (Max-Min) * 10.0) / 10.0 проверять каждый раз scrollinfo.nPos до посинения.
Но тоже ненадёжно Зависит от высоты окна, количества строк итд итп.

Возможно, я вообще что-то не так делаю и есть простой и надёжный способ, о котором я не знаю?
 
Последнее редактирование:

Анатолий Халак

Administrator
Команда форума

addewyd@

Member
По поводу процентов. Посмотрел. Грид на 62 строки (видимых 14, но это не важно). 10% Скроллит на 4 или 5 строк.

Кино здесь

Про видео. С этим у меня проблемы, я видео просто не воспринимаю. Особенно, когда мануалы/туториалы публикуют в виде роликов. Модно, но очень неудобно. В серьёзных случаях приходится руками набирать закадровый текст и вырезать нужные картинки. (по опыту: 10 минут видео преобразуются в страницу текста и 5-10 картинок. Но это тяжёлая работа)

Предложенные видео всё же посмотрел. Не заметил скроллинга, из движений только указатель выполняемой строки кода скачет.

Хоткеи — вы имеете ввиду стрелочками двигать? А если окно не в фокусе?
И, кажется, уже упоминал о проблеме: активность не возвращает результат. Как минимум успешно/неуспешно. Дошли до конца или нет. Или вообще ошибка win 1447 - окно не скроллится
 
Последнее редактирование:

Анатолий Халак

Administrator
Команда форума
Действительно, использование активности "Прокрутить" обязывает вычислять процент по формуле, где присутствует зависимости от общего количества элементов в таблице.
Что касается фокуса на таблице, то он нужен и для активности "Прокрутить", и для хоткеев, но хоткеями задача решается на первый взгляд более надежно. Нужно лишь придумать условие, по которому будет проверяться, прокручена ли вся таблица до конца или нет. Это можно сделать, проверяя на существование определенные UI-элементы (DataGridRow), либо, как вариант, сравнивая UI-элементы в одной позиции до и после нажатия на хоткей "Down".
По поводу улучшений активности "Прокрутить" подумаем, как минимум поставим вопрос о том, чтобы использовать дробные проценты прокрутки, а не целые.
 
Последнее редактирование:

addewyd@

Member
1) в общем случае заранее неизвестно количество строк в гриде. Да, можно вызвать каким-либо образом GetScrollInfo, но не всегда возможно.
2) Элемента DataGridRow в большинстве случаев нет (в УИ построенном на WPF можно ячейку выделить, в остальных случаях не обнаружилось. Вообще, редко где можно выделить с помощью Xpath окно со скроллом. В этом же PIX Studio не получилось. Получилось только в классических приложениях win32 и MFC)
3) Дробные проценты не помогут, проверено. Несколькими мессагами выше где-то упоминал, что прямой вызов element.Scroll(Activities.Desktop.Enums.ScrollDirection direction, double scrollPercent) не помогает. чуть меньше порогового значения (на 0.000...1) и мы в бесконечном цикле. Чуть больше — начинает пропускать строки.

Вопрос серьёзный. Робот должен работать 24/7 с большими объёмами данных и ошибаться как можно реже А если ошибка произошла, должна обязательно фиксироваться. А в варианте со скроллингом даже нельзя определить, сколько строк за один вызов прокручено, 0, 1 или больше.

Там где это возможно, применяется прямое обращение к БД, но это, скорее, исключение, в основном имеется только УИ.
 

Кирилл Серов

Administrator
Команда форума
Интересная задача!


Т.е. ячейки или строки не распознаются никак? Получается внутри таблицы не происходит распознавание элементов?

А если использовать ScrollBar и нажимать на прокрутку вниз? Можно ли так гарантировать прокрутку именно одной строки?
1612875723579.png
 

addewyd@

Member
нет, самый последний элемент в иерархии - "Pane", включает саму таблицу с заголовкам и скроллбары, если они в наличии.

1612882208031.png

/Window[@Name = '....]'/Pane[@ClassName = 'MDIClient' and @Name = 'Рабочее пространство']/Window[@Name = 'Настраиваемые параметры пользователя']/Pane[@ClassName = 'AfxFrameOrView120']

Это MFC

Ячейки, строки распознаются в WPF, WinWorms
Не распознаются в MFC, QT5

Кроме того не всегда можно выделить окно, которое в принципе можно таким образом прокручивать



Desktop.Core.UIElement Element;
// .....

Rect = Element.GetRectangle();
var hwnd = Desktop.Core.Win32.WindowFromPoint(Rect.Location);

_ScrollInfo scrollInfo = new _ScrollInfo();
scrollInfo.cbSize = (uint)Marshal.SizeOf(scrollInfo);
bool b = GetScrollInfo(hwnd, whatScrollBar, scrollinfo);
if(!b) errorCode = GetLastWin32Error();


Чаще всего возвращается
1447The window does not have scroll bars.ERROR_NO_SCROLLBARS


Картинка для примера, реально могут километровые портянки, которые необходимо обрабатывать построчно.
Читать данные ячеек, редактировать их. По даблклику вообще вылезает диалоговое окно, с которым тоже надо работать, по ПКМ - контекстное меню и так далее. То ещё веселье.
 
Последнее редактирование:

Who

New member
нет, самый последний элемент в иерархии - "Pane", включает саму таблицу с заголовкам и скроллбары, если они в наличии.

Посмотреть вложение 207

/Window[@Name = '....]'/Pane[@ClassName = 'MDIClient' and @Name = 'Рабочее пространство']/Window[@Name = 'Настраиваемые параметры пользователя']/Pane[@ClassName = 'AfxFrameOrView120']

Это MFC

Ячейки, строки распознаются в WPF, WinWorms
Не распознаются в MFC, QT5

Кроме того не всегда можно выделить окно, которое в принципе можно таким образом прокручивать



Desktop.Core.UIElement Element;
// .....

Rect = Element.GetRectangle();
var hwnd = Desktop.Core.Win32.WindowFromPoint(Rect.Location);

_ScrollInfo scrollInfo = new _ScrollInfo();
scrollInfo.cbSize = (uint)Marshal.SizeOf(scrollInfo);
bool b = GetScrollInfo(hwnd, whatScrollBar, scrollinfo);
if(!b) errorCode = GetLastWin32Error();


Чаще всего возвращается
1447The window does not have scroll bars.ERROR_NO_SCROLLBARS


Картинка для примера, реально могут километровые портянки, которые необходимо обрабатывать построчно.
Читать данные ячеек, редактировать их. По даблклику вообще вылезает диалоговое окно, с которым тоже надо работать, по ПКМ - контекстное меню и так далее. То ещё веселье.
Есть в окне возможность делать Ctrl+A/Ctrl+c?
 

addewyd@

Member
Есть, в некоторых случаях помогает, когда достаточно просто прочитать данные таблички.
 
Верх