Axapta хитрая.
Вот что происходит при переходе к основной таблице (принцип которого у вас используется в коде).
1. На сервере открывается курсор для такого запроса
X++:
select *
frrom Table
where Table.Field >= Value ...
где Table.Field - поле с которого произошел переход (или точнее LookupField() в args() формы)
Value - значение поля с которого произошел переход (или точнее LookupValue() в args() формы)
В буфер на клиенте выбирается некоторое количество записей (зависит от таблицы).
2. Курсор позиционируется на первой записи.
При перемещении назад по датасету (нажав PgUp, Up или вызвав сооответствующий метод) на сервере открывается курсор для такого запроса
X++:
select *
frrom Table
where Table.Key1 < Value ...
При этом для ORDER BY включается обратный порядок сортировки.
Строки в буфер на клиенте добавляются в обратном порядке.
Дальше при перемещении вперед или назад по датасоурсу, если не получены все строки с сервера, фетчится соответствующий открытый курсор.
При таком алгоритме работы Axpata'ы, если включить сортировку на табличной форме не по ключу перехода, то будет неправильно позиционироваться курсор после открытия формы
В форме InventBatch фактически выполняется перемещение по датасорсу ч/з ds.Next(), пока не найден нужный ItemId (InventBatch отпозиционирован движком по приведенному алгоритму).