How to Import, Read, Change Data from EXCEL in QTP/UFT

โšก Smart Summary

Importing, reading, and changing data from Excel in QTP/UFT relies on the built-in DataTable object, which loads a workbook into the run-time data table so every automation script can drive test steps from spreadsheet rows.

  • ๐Ÿ“ฅ Import: DataTable.Import loads an entire workbook, while DataTable.ImportSheet pulls one named sheet into a chosen destination sheet.
  • ๐Ÿ—‚๏ธ Header rule: The first spreadsheet row becomes the column names, so structure the sheet before the import runs.
  • ๐Ÿ”ข Row count: DataTable.GetSheet(1).GetRowCount returns the number of data rows and excludes the header row.
  • ๐ŸŽฏ Row pointer: Call DataTable.SetCurrentRow before each read so DataTable.Value returns the cell you expect.
  • โœ๏ธ Write back: Assigning to DataTable.Value changes a cell in memory only; DataTable.Export saves the sheet to disk.
  • ๐Ÿงฉ COM option: Create an Excel.Application object when formatting, formulas, or several open workbooks are required.
  • โš ๏ธ Cleanup: Always call Quit and release objects, otherwise EXCEL.EXE remains resident and locks the file.

How to Import, Read and Change Data from Excel in QTP/UFT

Spreadsheets remain the most common place where testers keep their input values, expected results, and environment settings. QTP, now sold as OpenText UFT One after the product moved from HP to Micro Focus and then to OpenText, reads those spreadsheets through the DataTable object. The sections below show the exact statements used to import a workbook, count its rows, read individual cells, change values, and write the sheet back to disk.

Steps to Import, Read, Change Data from EXCEL

Consider that you want to import the following Sales.xls workbook into your test.

Sales.xls source workbook opened in Excel before importing into UFT

Once the file is imported into UFT, the top row becomes the column header, so structure your data accordingly. Anything in row 1 is treated as a parameter name rather than as test data, and every remaining row is counted as a data row.

The syntax to import an entire Excel file is shown below.

DataTable.Import(FileName)

In our case the statement becomes the following. VBScript does not need parentheses when a method is called as a statement, so the plain form is used here.

DataTable.Import "D:\Automation\Sales.xls"

After the run, the imported rows appear in the run-time Data pane exactly as they were laid out in the workbook.

Imported Sales data shown in the UFT run-time Data Table pane

The syntax to import one particular sheet is shown next. SheetSource is the sheet inside the workbook and SheetDest is the destination sheet in the run-time data table.

DataTable.ImportSheet FileName, SheetSource, SheetDest

Use the GetRowCount method to get the number of data rows in a sheet. Each statement must sit on its own line.

DataTable.Import "D:\Automation\Sales.xls"
row = DataTable.GetSheet(1).GetRowCount
MsgBox row

The message box that appears reports the row total for the imported sheet.

MsgBox displaying the GetRowCount result for the imported Sales sheet

To move the pointer to a specific row, use the SetCurrentRow method. The second argument of DataTable.Value is the sheet number, not the row number, which is why the row pointer has to be moved separately.

DataTable.Import "D:\Automation\Sales.xls"

' In the code below, 1 is the sheet number
DataTable.SetCurrentRow 1
Row1 = DataTable.Value("Year", 1)

DataTable.SetCurrentRow 2
Row2 = DataTable.Value("Year", 1)

MsgBox "Year Row 1 = " & Row1 & "    Year Row 2 = " & Row2

Both values are read from the same column but from two different rows, and the message box prints them side by side.

MsgBox comparing the Year value of row 1 and row 2 of the data table

Use the Value method on the left of an assignment to change data in the imported sheet. The change lives in memory until you call Export, which writes the run-time data table back to an Excel file.

DataTable.SetCurrentRow 1
DataTable.Value("Year", 1) = 2026
DataTable.Export "D:\Automation\Sales_Updated.xls"

The edited cell is visible in the run-time Data pane straight after the assignment runs.

Run-time Data Table showing a cell updated through the DataTable.Value method

Opening the exported workbook confirms that the modified values were saved to disk rather than kept only for the duration of the run.

Exported Excel file opened in Excel showing the changed values saved by DataTable.Export

๐Ÿ’ก Tip: Export to a different file name from the one you imported. Writing back to the same open workbook is the fastest way to trigger a sharing violation and lose the run.

How to Read, Change and Export Excel Data: A Complete Example

The snippets above each demonstrate one method. In a real data-driven test they are combined into a single loop that walks every row, calculates something, stores the result, and exports the sheet. Assume the workbook Sales.xls holds the following four columns and three data rows.

Year Region Units Price
2023 East 120 25
2024 East 150 25
2025 West 200 30

The script below adds a Revenue column, fills it row by row, keeps a running total, and writes the finished sheet to a new file. AddParameter is used because the column does not exist in the source workbook; calling it for a column that already exists raises an error.

' Read, calculate and export Excel data in UFT One
Dim sh, rowCount, i, units, price, revenue, total

DataTable.Import "D:\Automation\Sales.xls"

Set sh = DataTable.GetSheet(1)
sh.AddParameter "Revenue", ""

rowCount = sh.GetRowCount
Print "Total rows imported: " & rowCount

total = 0
For i = 1 To rowCount
    DataTable.SetCurrentRow i

    units   = DataTable.Value("Units", 1)
    price   = DataTable.Value("Price", 1)
    revenue = CInt(units) * CInt(price)

    DataTable.Value("Revenue", 1) = revenue
    total = total + revenue

    Print "Row " & i & " | Year: " & DataTable.Value("Year", 1) & _
          " | Region: " & DataTable.Value("Region", 1) & _
          " | Revenue: " & revenue
Next

Print "Grand Total Revenue: " & total

DataTable.Export "D:\Automation\Sales_Revenue.xls"
Set sh = Nothing

Output:

Total rows imported: 3
Row 1 | Year: 2023 | Region: East | Revenue: 3000
Row 2 | Year: 2024 | Region: East | Revenue: 3750
Row 3 | Year: 2025 | Region: West | Revenue: 6000
Grand Total Revenue: 12750

Three points in this script matter more than the rest. First, GetRowCount returns 3 rather than 4 because the header row is consumed as column names. Second, SetCurrentRow is called at the top of every iteration; without it, all three iterations would read the same row. Third, values coming out of the data table are strings, so CInt is applied before the multiplication to avoid string concatenation instead of arithmetic. Skipping DataTable.Export would leave the calculated revenue visible in the Data pane but absent from any file on disk.

DataTable Object vs Excel COM Object in UFT

The DataTable object is not the only way to reach a spreadsheet. UFT scripts can also create an Excel.Application COM object and drive Excel directly. The two approaches solve different problems.

Aspect DataTable object Excel COM object
Excel installation Not required on the execution machine Microsoft Excel must be installed
Addressing style By column name and row pointer By cell coordinates, ranges, or named ranges
Iterations Rows drive test iterations automatically No link to iterations; looping is manual
Formatting and formulas Ignored; only values are read Full access to formulas, colours, and charts
Multiple workbooks One run-time table, sheets imported one at a time Any number of workbooks open at once
Results reporting Values appear in the UFT run results automatically Nothing is captured unless you report it yourself
Cleanup burden Handled by UFT You must close, quit, and release every object

The practical rule is simple. Use the DataTable object for straightforward parameterisation, where each spreadsheet row becomes one iteration of an automation testing run. Switch to the COM object only when you need something the data table cannot express, such as reading a formula result, writing a formatted report, or comparing two workbooks in the same script. The example below reads one cell, writes a status back, and shuts Excel down properly.

Dim xlApp, xlBook, xlSheet, cellValue

Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = False
xlApp.DisplayAlerts = False

Set xlBook  = xlApp.Workbooks.Open("D:\Automation\Sales.xls")
Set xlSheet = xlBook.Worksheets("Sheet1")

cellValue = xlSheet.Cells(2, 1).Value
Print "Cell A2 contains: " & cellValue

xlSheet.Cells(2, 5).Value = "Reviewed"
xlBook.Save

' Release everything, in this order
xlBook.Close False
xlApp.Quit
Set xlSheet = Nothing
Set xlBook  = Nothing
Set xlApp   = Nothing

Output:

Cell A2 contains: 2023

Cell A2 holds 2023 because row 1 of the worksheet is the header row and column A is Year. Notice that COM addressing is one-based and counts the header, whereas DataTable.SetCurrentRow 1 points at the first data row.

Common Errors When Using Excel with UFT and How to Fix Them

Most Excel problems in UFT come from a small set of repeatable mistakes. Recognising them saves a great deal of debugging time.

โš ๏ธ Warning: An orphaned EXCEL.EXE process is the single most common side effect of COM automation. Every CreateObject("Excel.Application") that is not matched by Quit plus Set โ€ฆ = Nothing leaves a hidden Excel instance running. After a few hundred test runs the execution machine is out of memory and the source workbook is locked for editing.

  • Excel stays in memory. Close the workbook, call xlApp.Quit, then release the sheet, workbook, and application objects in that order. Releasing the application first leaves a live reference and keeps the process alive.
  • Changes disappear after the run. DataTable.Value writes to the run-time data table only. Without DataTable.Export, nothing reaches the file system.
  • “The column does not exist” or an invalid parameter error. The column name passed to DataTable.Value must match the header cell exactly, including trailing spaces. Use AddParameter to create a column before writing to it.
  • Every iteration reads the same values. SetCurrentRow was not called inside the loop, so the row pointer never moved.
  • Off-by-one row counts. GetRowCount excludes the header row. A workbook with a header and ten records returns 10, not 11.
  • Path and permission failures. Hard-coded paths such as D:\Automation\Sales.xls break on other machines. Build the path from an environment variable so the same script runs on every agent.
  • Merged cells and multiple header rows. The import expects exactly one header row of unique names. Merged cells produce blank or duplicated parameter names.
  • Sharing violation on export. The destination file cannot be open in Excel while Export runs. Close it first, or export to a timestamped file name.

A useful habit is to wrap COM cleanup in an On Error Resume Next block placed in a dedicated recovery function, so a mid-script failure still shuts Excel down. When Excel data feeds a formal test case repository, the same discipline applies to results: export once, verify the file exists, then attach it to the run.

To go further with the topics touched on here, work through the full QTP/UFT tutorial for the wider framework, learn how to push results into ALM from UFT, review the fundamentals in software testing, and compare the approach with data-driven scripting in Selenium.

FAQs

UFT imports .xls, .xlsx and .csv files into the run-time data table. Export always produces a .xls workbook, so a converter or the Excel COM object is needed when the downstream system requires the newer .xlsx format.

The design-time table is saved with the test and stays unchanged. The run-time table is a copy created when execution starts. Imports and value assignments affect only the run-time copy, which is discarded unless it is exported.

No for the DataTable object, which parses the workbook itself. Yes for any script that calls CreateObject(“Excel.Application”), because that route automates a real Excel instance and fails immediately on a machine without it.

Yes. Call ImportSheet once per sheet with a different destination sheet name each time. Global data belongs on the Global sheet, while action-specific values belong on the matching action sheet so iterations stay independent.

Yes, and the loop skeleton is usually correct. Verify two things by hand: that SetCurrentRow sits inside the loop, and that numeric cells are converted with CInt or CDbl. Generated code frequently omits both.

AI features in modern UFT One releases recognise controls visually, so a renamed field no longer breaks every row of a data set. AI can also suggest additional boundary rows, widening spreadsheet coverage without manual test design.

Summarize this post with: