Quantcast
Channel: Silk Test Knowledge Base
Viewing all articles
Browse latest Browse all 105

Read and Write to an Excel spreadsheet without a DSN connection

$
0
0
Revision 2 posted to Silk Test Knowledge Base by DaiG on 1/25/2016 10:40:15 PM

Note:

------------------

If you do not have the Microsoft Office Primary Interop Assemblies installed in either Silk4Net or Silk Test Workbench, you can download the installer package from here:

Office 2007 - http://www.microsoft.com/en-us/download/details.aspx?id=18346
Office 2010 - http://www.microsoft.com/en-us/download/details.aspx?id=3508

If you are using Silk Test Workbench, please see

http://microfocus.telligenthosting.net/borland/test/silk_test/w/knowledge_base/26421.silk-test-workbench-will-not-reference-the-microsoft-office-primary-interop-assemblies.aspx


before continuing.

------------------


It is customary to use an ActiveData asset to read and write to an Excel spreadsheet but there are limitations to this approach; for example, ActiveData can only access a single sheet within the named workbook and this sheet cannot be changed dynamically during testing. ActiveData reads and writes single rows but there are times when it would be more convenient to read and write to a single cell, to read and write to multiple rows, to read and write a complete Excel sheet in one go or to add a new sheet to an existing workbook during testing.

The Microsoft Office Primary Interop Assemblies provide us with a series of methods that don't need a DSN to read and write to an Excel spreadsheet from both Silk Test Workbench and Silk4Net. The attached archive contains the class library as a dll (ExcelRW.dll) and a simple wrapper for the StreamReader and StreamWriter methods in dotNet (mffileio.dll). We'll use the wrapper to output Excel data to a text file. Wherever you put these dlls, if you are using Silk Test Workbench then you MUST ensure that the required Interop Assembly is in the same folder as ExcelRW.dll.

For both Silk Test Workbench and Silk4Net you must then add a reference to the Interop Assembly and to the ExcelRW dll.

The ExcelRW class library contains the following public methods:

addSheet()
getError()
getSheets()
readOneCell()
readOneRow()
readOneSheet()
writeOneCell()
writeOneRow()
writeSheet()
killExcelProcesses()

It also has a reasonably robust error reporting system so that in the event of a failed call you can query the dll for the exact error.

The code examples in the archive are written in vb.Net as this is common to both Silk Test IDEs.

Read Methods.

Please note that if any optional parameters are required then ALL preceeding optional parameters must also be filled in.

 

getError()

Returns the last internal error message as a string. The messages are:

error0 = "Success"
error1 = "Workbook not found"
error2 = "Sheet not found"
error3 = "Unknown error"
error4 = "No data"
error5 = "Sheet already exists"

e.g.

dim excelRW as new excelrW.excelrw

' Do something...
console.writeline(excelrw.getError())

So if the last internal error was error1 then

console.writeline(excelrw.getError())

will print

Workbook not found

 


readOneCell(ByVal xls As String, ByVal cell As String, Optional ByVal sheetname As String = "Sheet1")

xls = the path to the spreadsheet including the name of the spreadsheet.
cell = the alphanumeric specifier for the cell to receive the data e.g. G6, A9, BF3, etc..
sheetname = the name of the specific sheet within the workbook to read the cell data from. The default is 'Sheet1'.

Returns the data from a single specified cell as a string.

e.g.

dim excelRW as new excelrW.excelrw
dim sData as string = nothing

try
  sData=readOneCell("c:\temp\test.xls","A6")
catch
  console.writeline(excelrw.getError())
end try


readOneRow(ByVal xls As String, Optional ByVal sheetname As String = "Sheet1", Optional ByVal row As Integer = 0, Optional ByVal sep As String = "default")

xls = the path to the spreadsheet including the name of the spreadsheet
sheetname = the name of the specific sheet within the workbook to read the cell data from. The default is 'Sheet1'.
row = 0 to continue from the last row, -1 to reset to the start of the sheet, any valid number to read that specific row (default is zero).
sep = any valid alpha character to be used as a separator for the returned data. The default is a comma (chr(44)).

Returns a complete row of data from the specified row as a string. The individual cells within the string are delinated by sep.

e.g.

dim excelRW as new excelrW.excelrw
dim sData as string = nothing

try
  sData=readOneRow("c:\temp\test.xls","customers")
catch
  console.writeline(excelrw.getError())
end try

If the row parameter is never changed then each call to readOneRow() will return the data from each succeeding row and will return 'eof' when there is no more data. If a row number is specified at any point then the following call will begin from the specified row+1. To reset the data read to the beginning of the sheet, pass in row as -1 (minus one).

In this and other methods with the 'sep' parameter, if you require to change the default separator to e.g. a full stop (decimal point) but do not want to change the row number then the method call will be

sData=readOneRow("c:\temp\test.xls","customers",0,chr(46))

or

sData=readOneRow("c:\temp\test.xls","customers",0,".")

i.e. a parameter for 'row' must be provided. Once the separator has been changed it will remain changed for the remainder of the session or until you make it something else. To return to default you will need to supply the parameter as chr(44) or ",". Changing the separator affects all methods that have 'sep' as an optional parameter.


readOneSheet(ByVal xls As String, Optional ByVal sheetname As String = "Sheet1")

xls = the path to the spreadsheet including the name of the spreadsheet.
sheetname = the name of the specific sheet within the workbook to read the cell data from. The default is 'Sheet1'.

Returns all the data on the sheet as a two-dimensional array of objects.

e.g.

dim excelRW as new excelrW.excelrw
dim obData As object(,) = nothing

try
  obData = excelRW.readOneSheet("c:\temp\test.xls", "customers")
catch
  console.writeline(excelrw.getError())
end try

The object array holds the data as row/column and is zero-based, so the data from cell B5 would be in obData(4,1). The size of the object array can be found by using array.GetUpperBound(0) for the number of rows and array.GetUpperBound(1) for the number of columns. This is illustrated in the attached sample.


getSheets(ByVal xls As String)

getSheets() is used internally to ensure that operations are carried out on the correct workbook sheet. Although it can be seen externally it will not return any meaningful data.


Write Methods.

The write methods all return the last internal error message directly.


writeOneCell(ByVal xls As String, ByVal cell As String, ByVal data As String, Optional ByVal sheetname As String = "Sheet1", Optional ByVal create As String = "false") as string

xls = the path to the spreadsheet including the name of the spreadsheet.
cell = the alphanumeric specifier for the cell to receive the data e.g. G6, A9, BF3, etc..
data = the data to be written to the cell.
sheetname = the name of the specific sheet within the workbook to write the cell data to. The default is 'Sheet1'.
create = if the spreadsheet does not exist then create it. Default is false (don't create).

e.g.

dim excelRW as new excelrW.excelrw
dim result as string = nothing

result=excelRW.writeOneCell("c:\temp\test.xls", "B3", "John Doe", "customers", true)
console.writeline(result)

This will create the spreadsheet text.xls if it doesn't exist in c:\temp and will name the first sheet as "customers". It will then enter "John Doe" into cell B3. Finally, the last internal error message will be placed into 'result'.

Use the 'create' parameter with care as a typographical error in the path or name of the Excel spreadsheet can lead to a spreadsheet being created in another folder and/or under a different name.


writeOneRow(ByVal xls As String, ByVal data As String, Optional ByVal sheetname As String = "Sheet1", Optional ByVal row As Integer = -1, Optional ByVal create As String = "false", Optional ByVal sep As String = "default") as string

xls = the path to the spreadsheet including the name of the spreadsheet.
data = the data to be written to the row. Must be presented in csv format.
sheetname = the name of the specific sheet within the workbook to write the data to. The default is 'Sheet1'.
row = 0 to continue from the last row on the sheet or any valid number to write to that specific row (default is zero).
create = if the spreadsheet does not exist then create it. Default is false (don't create).
sep = any valid alpha character to be used as a separator for the data string. The default is a comma (chr(44)).

e.g.

dim excelRW as new excelrW.excelrw
dim sData as string = nothing
dim result as string = nothing

sData="write,one,row,test"

result=excelRW.writeOneRow("c:\temp\test.xls", sData)
console.writeline(result)

Note: this call will fail if sep is not the same as the separator used in the data string. All data held in sData will be written to a single cell.


writeSheet(ByVal xls As String, ByVal data(,) As Object, Optional ByVal sheetname As String = "Sheet1", Optional ByVal create As String = "false") as string

xls = the path to the spreadsheet including the name of the spreadsheet.
data = the data to be written presented as an array of objects
sheetname = the name of the specific sheet within the workbook to write the data to. The default is 'Sheet1'.
create = if the spreadsheet does not exist then create it. Default is false (don't create).

e.g.

dim excelRW as new excelrW.excelrw
dim obData(,) as object = nothing
dim result as string = nothing

' Fill an object array
For iRow = 0 To 5
  For iCol = 0 To 5
    obData(iRow, iCol) = iRow * iCol
  Next iCol
Next iRow

sheetName = "writeTest"
result=excelRW.writeSheet("c:\temp\writeExcel.xls", obData, sheetName)
console.writeline(result)


addSheet(ByVal xls As String, ByVal sheetname As String, Optional ByVal create As String = "false")

xls = the path to the spreadsheet including the name of the spreadsheet.
sheetname = the name of the sheet to be added.
create = if the spreadsheet does not exist then create it. Default is false (don't create).

Note that addSheet() requires a sheetname. If you want the next sheet in the default series e.g. 'Sheet4' then supply sheetname as 'none'.

e.g.

dim excelRW as new excelrW.excelrw
dim result as string = nothing

result=excelRW.addSheet("c:\temp\test.xls", "customers")
console.writeline(result)

If the sheet named "customers" does not exist in the current workbook then it will be created. addSheet() is used internally by the create parameter in the write methods but can be used externally if specifically required.

killExcelProcesses()

The Interop Assemblies can leave orphaned threads running in the Processes stack in Task Manager, particularly if Excel has come to a crash stop for any reason. ExcelRW will normally clean up its own Excel.exe processes behind itself, but removal of all of these processes is not guaranteed. You can force a cleanup by using the killExcelProcess() call. However it isn't possible to tell if those processes belong to ExcelRW or to your newly-created expenses spreadsheet. Ensure that all other Excel instances are closed before running any tests involving ExcelRW.

In addition, if you are running ActiveData then killExcelProcesses() will also kill the ActiveData calls. Ensure that you do not use this method until you have exited from all ActiveData code i.e. the safest place to put it is the very last line of the test script.

 

Using the sample archive

The archive contains a sample spreadsheet, the ExcelRW and MFfileIO dlls, a complete Visual Studio 2010 Silk4Net solution and a Silk Test Workbench asset xml file. The spreadsheet (test1.xlsx) and the DLLs should be placed in your c:\temp folder; if c:\temp is not available then you will need to change the paths in the test code and change the DLL references to point to the new folder.

The results of each individual test are written to c:\temp\excelresults.txt and during the execution of the test a second spreadsheet (c:\temp\writetext.xlsx) is created. Again, the path to both files can be changed in the script.

(Please visit the site to view this file)

Tags: write, Assemblies, read, interop, office, EXCEL, odbc, DSN

Viewing all articles
Browse latest Browse all 105

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>