src/sap.ui.table/src/sap/ui/table/TableScrollExtension.js
function(oTable) {
			var oScrollExtension = oTable._getScrollExtension();
			var iMaxFirstRenderedRowIndex = oTable._getMaxFirstRenderedRowIndex();
			var iNewFirstVisibleRowIndex = VerticalScrollingHelper.getRowIndexAtCurrentScrollPosition(oTable);
			var iOldFirstVisibleRowIndex = oTable.getFirstVisibleRow();
			var bNewFirstVisibleRowInBuffer = iNewFirstVisibleRowIndex < 0;
			var bOldFirstVisibleRowInBuffer = iOldFirstVisibleRowIndex >= iMaxFirstRenderedRowIndex;
			var bFirstVisibleRowChanged = iNewFirstVisibleRowIndex !== iOldFirstVisibleRowIndex;
			var bRowsUpdateRequired = bFirstVisibleRowChanged && !(bNewFirstVisibleRowInBuffer && bOldFirstVisibleRowInBuffer);

			if (bRowsUpdateRequired) {
				var bExpectRowsUpdatedEvent = !bOldFirstVisibleRowInBuffer || iNewFirstVisibleRowIndex !== iMaxFirstRenderedRowIndex;

				if (bNewFirstVisibleRowInBuffer) {
					// The actual new first visible row cannot be determined yet. It will be done when the inner scroll position gets updated.
					iNewFirstVisibleRowIndex = iMaxFirstRenderedRowIndex;
				}

				log("updateFirstVisibleRow: From " + iOldFirstVisibleRowIndex + " to " + iNewFirstVisibleRowIndex, oTable);

				oTable.setFirstVisibleRow(iNewFirstVisibleRowIndex, true, bNewFirstVisibleRowInBuffer);

				if (bExpectRowsUpdatedEvent) {
					VerticalScrollingHelper.setOnRowsUpdatedPreprocessor(oTable, function(oEvent) {
						log("updateFirstVisibleRow - onRowsUpdatedPreprocessor: Reason " + oEvent.getParameters().reason, this);

						oScrollExtension.updateInnerVerticalScrollPosition();

						if (bNewFirstVisibleRowInBuffer) {
							var iCurrentFirstVisibleRow = this.getFirstVisibleRow();
							var bFirstVisibleRowNotChanged = iNewFirstVisibleRowIndex === iCurrentFirstVisibleRow;

							// The firstVisibleRow was previously set to the maximum first visible row index while suppressing the event. If the first
							// visible row is not adjusted in #updateInnerVerticalScrollPosition, make sure the event is called here.
							if (bFirstVisibleRowNotChanged) {
								this.setProperty("firstVisibleRow", -1, true);
								this.setFirstVisibleRow(iCurrentFirstVisibleRow, true);
							}
						}

						return false;
					});
				} else {
					log("updateFirstVisibleRow: Update inner vertical scroll position", oTable);
					oScrollExtension.updateInnerVerticalScrollPosition();
				}

			} else if (TableUtils.isVariableRowHeightEnabled(oTable)) {
				log("updateFirstVisibleRow: Update inner vertical scroll position", oTable);
				oScrollExtension.updateInnerVerticalScrollPosition();
			}
		}
function(oTable) {
			var oScrollExtension = oTable._getScrollExtension();
			var iMaxFirstRenderedRowIndex = oTable._getMaxFirstRenderedRowIndex();
			var iNewFirstVisibleRowIndex = VerticalScrollingHelper.getRowIndexAtCurrentScrollPosition(oTable);
			var iOldFirstVisibleRowIndex = oTable.getFirstVisibleRow();
			var bNewFirstVisibleRowInBuffer = iNewFirstVisibleRowIndex < 0;
			var bOldFirstVisibleRowInBuffer = iOldFirstVisibleRowIndex >= iMaxFirstRenderedRowIndex;
			var bFirstVisibleRowChanged = iNewFirstVisibleRowIndex !== iOldFirstVisibleRowIndex;
			var bRowsUpdateRequired = bFirstVisibleRowChanged && !(bNewFirstVisibleRowInBuffer && bOldFirstVisibleRowInBuffer);

			if (bRowsUpdateRequired) {
				var bExpectRowsUpdatedEvent = !bOldFirstVisibleRowInBuffer || iNewFirstVisibleRowIndex !== iMaxFirstRenderedRowIndex;

				if (bNewFirstVisibleRowInBuffer) {
					// The actual new first visible row cannot be determined yet. It will be done when the inner scroll position gets updated.
					iNewFirstVisibleRowIndex = iMaxFirstRenderedRowIndex;
				}

				log("updateFirstVisibleRow: From " + iOldFirstVisibleRowIndex + " to " + iNewFirstVisibleRowIndex, oTable);

				oTable.setFirstVisibleRow(iNewFirstVisibleRowIndex, true, bNewFirstVisibleRowInBuffer);

				if (bExpectRowsUpdatedEvent) {
					VerticalScrollingHelper.setOnRowsUpdatedPreprocessor(oTable, function(oEvent) {
						log("updateFirstVisibleRow - onRowsUpdatedPreprocessor: Reason " + oEvent.getParameters().reason, this);

						oScrollExtension.updateInnerVerticalScrollPosition();

						if (bNewFirstVisibleRowInBuffer) {
							var iCurrentFirstVisibleRow = this.getFirstVisibleRow();
							var bFirstVisibleRowNotChanged = iNewFirstVisibleRowIndex === iCurrentFirstVisibleRow;

							// The firstVisibleRow was previously set to the maximum first visible row index while suppressing the event. If the first
							// visible row is not adjusted in #updateInnerVerticalScrollPosition, make sure the event is called here.
							if (bFirstVisibleRowNotChanged) {
								this.setProperty("firstVisibleRow", -1, true);
								this.setFirstVisibleRow(iCurrentFirstVisibleRow, true);
							}
						}

						return false;
					});
				} else {
					log("updateFirstVisibleRow: Update inner vertical scroll position", oTable);
					oScrollExtension.updateInnerVerticalScrollPosition();
				}

			} else if (TableUtils.isVariableRowHeightEnabled(oTable)) {
				log("updateFirstVisibleRow: Update inner vertical scroll position", oTable);
				oScrollExtension.updateInnerVerticalScrollPosition();
			}
		}
function ( oTable ) { var oScrollExtension = oTable . _getScrollExtension ( ) ; var iMaxFirstRenderedRowIndex = oTable . _getMaxFirstRenderedRowIndex ( ) ; var iNewFirstVisibleRowIndex = VerticalScrollingHelper . getRowIndexAtCurrentScrollPosition ( oTable ) ; var iOldFirstVisibleRowIndex = oTable . getFirstVisibleRow ( ) ; var bNewFirstVisibleRowInBuffer = iNewFirstVisibleRowIndex < 0 ; var bOldFirstVisibleRowInBuffer = iOldFirstVisibleRowIndex >= iMaxFirstRenderedRowIndex ; var bFirstVisibleRowChanged = iNewFirstVisibleRowIndex !== iOldFirstVisibleRowIndex ; var bRowsUpdateRequired = bFirstVisibleRowChanged && ! ( bNewFirstVisibleRowInBuffer && bOldFirstVisibleRowInBuffer ) ; if ( bRowsUpdateRequired ) { var bExpectRowsUpdatedEvent = ! bOldFirstVisibleRowInBuffer || iNewFirstVisibleRowIndex !== iMaxFirstRenderedRowIndex ; if ( bNewFirstVisibleRowInBuffer ) { // The actual new first visible row cannot be determined yet. It will be done when the inner scroll position gets updated. iNewFirstVisibleRowIndex = iMaxFirstRenderedRowIndex ; } log ( "updateFirstVisibleRow: From " + iOldFirstVisibleRowIndex + " to " + iNewFirstVisibleRowIndex , oTable ) ; oTable . setFirstVisibleRow ( iNewFirstVisibleRowIndex , true , bNewFirstVisibleRowInBuffer ) ; if ( bExpectRowsUpdatedEvent ) { VerticalScrollingHelper . setOnRowsUpdatedPreprocessor ( oTable , function ( oEvent ) { log ( "updateFirstVisibleRow - onRowsUpdatedPreprocessor: Reason " + oEvent . getParameters ( ) . reason , this ) ; oScrollExtension . updateInnerVerticalScrollPosition ( ) ; if ( bNewFirstVisibleRowInBuffer ) { var iCurrentFirstVisibleRow = this . getFirstVisibleRow ( ) ; var bFirstVisibleRowNotChanged = iNewFirstVisibleRowIndex === iCurrentFirstVisibleRow ; // The firstVisibleRow was previously set to the maximum first visible row index while suppressing the event. If the first // visible row is not adjusted in #updateInnerVerticalScrollPosition, make sure the event is called here. if ( bFirstVisibleRowNotChanged ) { this . setProperty ( "firstVisibleRow" , - 1 , true ) ; this . setFirstVisibleRow ( iCurrentFirstVisibleRow , true ) ; } } return false ; } ) ; } else { log ( "updateFirstVisibleRow: Update inner vertical scroll position" , oTable ) ; oScrollExtension . updateInnerVerticalScrollPosition ( ) ; } } else if ( TableUtils . isVariableRowHeightEnabled ( oTable ) ) { log ( "updateFirstVisibleRow: Update inner vertical scroll position" , oTable ) ; oScrollExtension . updateInnerVerticalScrollPosition ( ) ; } }
Adjusts the first visible row to the current vertical scroll position.

@param {sap.ui.table.Table} oTable Instance of the table.
Adjusts the first visible row to the current vertical scroll position .