Home     Products      Support      Corporate     Sign In 

Support Knowledge Base, Article 1216

Product
ExcelWriter
Version
6.x
Title
Selective row copying from one worksheet to another (.NET)
Problem

How can I select a group of rows that have specific value in a cell/column then copy that range to a new sheet within the same workbook?

Solution
Often it necessary to filter the rows on one worksheet based on a certain criteria and copy over the affected rows to a separate worksheet. It is fairly easy to achieve this result with a little coding.

ExcelApplication object allows you to fully parse and design the excel document from your code, therefore giving you the ability to provide all the conditional logic to structure your final report.

Given the following data in one worksheet:

Company Name
PRICES
Date Open High Low Close Volume Adj Close*
5-Jul-0620.4720.4720.1320.28336,40020.28
3-Jul-0620.9721.0720.8521.05115,00021.05
30-Jun-0621.2721.2721.0221.13215,70021.13
29-Jun-0620.421.0220.3821.02314,00021.02
28-Jun-0620.3720.3720.0520.14403,90020.14
27-Jun-0620.2420.2419.819.86257,70019.86
26-Jun-0620.220.2720.0520.22703,70020.22
23-Jun-0620.4520.4520.1720.2302,50020.2
22-Jun-0620.320.520.0720.26291,70020.26
21-Jun-0620.0820.4520.0420.31160,00020.31
20-Jun-0620.1220.22020.03278,50020.03
19-Jun-0620.3320.3720.0620.11301,10020.11
16-Jun-0620.0320.3120.0320.16480,80020.16
15-Jun-0619.8220.519.8220.42301,00020.42
14-Jun-0619.419.6619.3819.61211,00019.61
13-Jun-0619.2519.5318.9619.09523,70019.09
12-Jun-0620.4520.5620.1120.11239,90020.11
9-Jun-0620.1620.5320.1120.22297,60020.22
8-Jun-0619.320.2119.2520.151,641,20020.15
7-Jun-0621.3521.4121.2121.29684,70021.29
6-Jun-0622.1522.1521.5121.67299,00021.67
5-Jun-0622.5122.5121.8921.91293,30021.91
2-Jun-0622.6322.7822.522.7754,10022.7
1-Jun-0621.922.2421.8622.24281,20022.24
* Criteria for selected rows (blue highlight) to copy is volume < 300,000

Result sheet should contain:

3-Jul-0620.9721.0720.8521.05115,00021.05
30-Jun-0621.2721.2721.0221.13215,70021.13
27-Jun-0620.2420.2419.819.86257,70019.86
22-Jun-0620.320.520.0720.26291,70020.26
21-Jun-0620.0820.4520.0420.31160,00020.31
20-Jun-0620.1220.22020.03278,50020.03
14-Jun-0619.419.6619.3819.61211,00019.61
12-Jun-0620.4520.5620.1120.11239,90020.11
9-Jun-0620.1620.5320.1120.22297,60020.22
6-Jun-0622.1522.1521.5121.67299,00021.67
5-Jun-0622.5122.5121.8921.91293,30021.91
1-Jun-0621.922.2421.8622.24281,20022.24

Algorithm

  1. Loop through the cells and evaluate your test expression. In this case the cells to test are in the Volume column.
  2. If the expression evaluates to false, move on to the next row value in our test column.
  3. If the expression evaluates to true, call a helper function CopyWorksheetRow (sample below) to copy the values of current row from original worksheet to the destination worksheet.

Helper Function

/// <summary>
/// Copies values of up to 20 columns for a given row from the original sheet 
///   to the destination sheet
/// </summary>
/// <param name="origin">Worksheet object from which to copy from</param>
/// <param name="destination">Worksheet object to which to copy to</param>
/// <param name="row_from">Row number to copy from the origin to the 
///   desination</param>
public static void CopyWorksheetRow(Worksheet origin, Worksheet destination, 
    int row_from)
{
    // create an area of 1 row / 20 columns  (Note our sample only has 7 columns)
    Area selected_row = origin.CreateArea(row_from, 0, 1, 20);

    // out of that area extract only the cells 
    // with values (Note this will select that area of only 7 columns)
    Area populated_cells = selected_row.PopulatedCells;

    for(int x = 0; x < populated_cells.ColumnCount; x++)
    {
      destination.Cells[row_to_start_at,x].Value = populated_cells[0, x].Value;
      destination.Cells[row_to_start_at,x].Style = populated_cells[0, x].Style;
    }

    row_to_start_at++;
}

Code to test the condition

ExcelApplication xap = new ExcelApplication();
Workbook wb = xap.Open(Page.MapPath("datadoc.xls"));

Worksheet data_sheet = wb.Worksheets[0];
Worksheet filtered_datasheet = wb.Worksheets.CreateWorksheet("mysheet", 1);

// set up a loop to look throught the cells in column 6 (indexed as 5) from
//   rows 6 to 71
for(int x = 5; x < 71; x++)
{
    int cellval = int.Parse(data_sheet.Cells[x, 5].Value.ToString());

    // if the cells value matches our criteria 
    // call a function to copy this row onto a separate sheet.  
    // in my case I want to copy the rows where 
    // the volume of stock traded is under 300,000
    if(cellval < 300000)
    {
        CopyWorksheetRow(data_sheet, filtered_datasheet, 
            data_sheet.Cells[x, 5].RowNumber);
    }
}

//Save to disk on the server
xap.Save(wb, Page.MapPath("C:\\MyReports\\output.xls"));

Notes:

Although this sample is written in C# the same principles apply if you are using the ExcelApplication object as a COM component.
Related Links
OfficeWriter Home Page
Purchase OfficeWriter
OfficeWriter Enterprise Edition
Latest OfficeWriter News
OfficeWriter: Programmatic Runtime Control

Attachments
Attachments/KB1216_SelectiveRowCopy.zip
Created : 2/8/2007 5:49:30 PM (last modified : 7/19/2007 10:11:43 AM)

Rate this article!

 
Comments



Copyright 2006 © SoftArtisans, Inc. All Rights Reserved.

Site Map     |     Privacy Policy     |     Contact Us