Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
Private Sub CalculateCells()
Dim cellcount As Double
Dim Sheet
cellcount = 0
For Each Sheet In ActiveWorkbook.Worksheets
cellcount = cellcount + Sheet.UsedRange.Cells.Count
Next


Dim message As String
message = "Total cells in workbook: " & vbCrLf & FormatNumber(Round(cellcount), 0) & vbCrLf
message = message & "Approximate max memory required (at 400 bytes per cell): " & vbCrLf
message = message & FormatNumber(Round(cellcount * 400), 0) & " bytes " & vbCrLf
message = message & Math.Round(((cellcount / 1024 / 1024 / 1024) * 400), 2) & " gigabytes"
MsgBox (message)

End Sub

Best Practices

Avoid Referencing Empty Cells

As noted previously, this cell will occupy up to 400 bytes of memory because several other objects have to be instantiated to hold the cell's attributes. Consequently, you should avoid looping through cells that might be empty, since doing so will create Cell objects that you may not need.

Use ExcelApplication before ExcelTemplate

To conserve memory, we recommend pre-processing a partial template with the ExcelApplication before passing the file to ExcelTemplate for importing data. See Preprocessing vs. PostProcessing.

Cache frequently

If you have large reports which are requested often but whose data changes infrequently, you may want to consider using ExcelWriter to generate the document once and then stream it to multiple users. This may be appropriate if the data is changed on a predictable schedule, or it is easy to check to see if the data has been changed. If you want the user to see the most recent data, then you will need to know when new data is available so you can regenerate the report.

...

When a user requests an Excel document, you can first check to see if there is new data. If there is, you can generate a new report and save it to disk. You can then stream that file to the user. We have a KB article which describes how to stream a file to the user that was previously saved to the disk with ExcelWriter.

Apply Styles to areas and not cells

Every time Cell.Style is accessed, ExcelWriter instantiates a separate Style object. To reduce file size bloating, we recommend using Global styles and setting styles on groups of cells. For details, see Effective Use of Styles.

Use InsertRows instead of InsertRow

The Worksheet class has both an InsertRows and an InsertRow method. If you are only inserting one row, then you should use InsertRow; however, if you are inserting multiple rows, you should make one call to InsertRows and pass the number of rows that you want to insert. For example:

...

Vbnet
1
1

'Where you want to insert new rows
Dim atRow As Integer = 10

'Determine how many rows you'll need to insert
Dim numRowsToInsert As Integer = 4

'Insert the desired number of rows. This will be much faster
'than multiple calls to InsertRow.
ws.InsertRows(atRow, numRowsToInsert)

Avoid calling AutoFitWidth on a lot of data

The ColumnProperties.AutoFitWidth and Area.AutoFitWidth methods are useful for making a column exactly wide enough to fit its contents. However, when there is a lot of data they can take a long time to execute, because they have to go through each row of data and calculate the width of the Cell's contents. Consequently, it is best to use only for columns with small amounts of data that you want to make sure are spaced correctly.

...

While this will not be as accurate as AutoFitWidth, it will be significantly faster.

Use DataReaders instead of DataTables

The Worksheet.ImportData method takes several different kinds of data types. DataReaders will read data directly from your data source into ExcelApplication's object model, and consequently use less memory and time than other data types. DataTables, DataViews, and arrays must all create an object in memory which contains the data before you can pass that object to ExcelApplication. ExcelApplication will then import the data into its object model. As a result, the data is stored in memory twice for these data types, as opposed to the DataReader where it is stored only once.

DataTables, DataViews, and arrays all use approximately the same amount of memory; however, there is a slight difference in speed. Two dimensional and jagged object arrays will be imported slightly faster, while DataTables and DataViews take approximately 10% longer to import. However, DataReaders remain the fastest, since they do not need to read the data into an object before importing it into ExcelApplication.

Use the newest version OfficeWriter

We are always working to improve the efficiency of ExcelWriter. Make sure to use the latest version of the product to take advantage of these improvements. See the OfficeWriter Change Log for more details.

Example code