Jump to content
GringoStarr

ExcelApp.WorkBooks.Open() memory leak

Recommended Posts

I've written a procedure that opens .csv files and saves them
in an excel workbook. It works fine, however, I noticed that
memory is not being released. After some checking I found that
it is the ExcelApp.Workbooks.Open() function that's not releasing
memory. Here's the code:

for var CSVItem in CSVDataDict do with CSVItem do begin
  const LineCount = Value.Count - 2;
  const CSVFile = Path + Key + '.csv';
  var ColumnWidths : IntegerArray;

  TFile.WriteAllText(CSVFile, Value.GetText, Encoding);
  SrcWorkBook := ExcelApp.Workbooks.Open(CSVFile, EmptyParam, EmptyParam, 
                 EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
                 EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, 
         EmptyParam, EmptyParam, LCID);
  ExcelWorkSheet := SrcWorkBook.Worksheets[1] as _Worksheet;
  CalculateColumnWidths(Key, ColumnWidths, Value);
  SetWorkSheetAttributes(Key, ExcelWorkSheet, ColumnWidths, LineCount);
  Count := ExcelWorkBook.Worksheets.Count;
  ExcelWorkSheet.Copy(EmptyParam, ExcelWorkBook.Worksheets[Count], LCID);
end;

I'm using Excel2010 in my application. I'm kind of new to Delphi Pascal
and it's hard to find good examples on how to use Excel Automation. Maybe
I'm not doing it right or is there a problem with memory leaks in the 
Workbooks.Open() function?

Share this post


Link to post

Your code snippet is too incomplete to say for sure but are you ever freeing the SrcWorkbook and ExcelWorkSheet instances you get there? I don't remember whether these are interface types or class wrappers, you have to check the source of the Excel2010 to see what they are.  If the two variables are defined in a local scope and are interface types they would be released automatically but not if they are objects...

Share this post


Link to post

Sorry about that. I posted it to the wrong forum. I found out that it's not the WorkBooks.Open()

statement but TFile.WriteAllText(...). It's the Value.GetText statement, which I didn't expect.

Share this post


Link to post

Forgot to mention that. It's a TStringList. CSVDataDict is a TDictionary<String, TStringList>.

Running the for-loop

var TextData : String;
for var CSVItem in CSVDataDict do with CSVItem do begin
  TextData := CSVItem .GetText;
end

 

results in memory leakage. Removing the assignment statement inside the for-loop

there is no leakage.

Share this post


Link to post

I don't know why but the memory leakage disappeared when I use Value.Text instead of Value.GetText

in the statement TFile.WriteAllText(CSVFile, Value.GetText, Encoding).

Share this post


Link to post

I don't know if you missed the last 3 posts I sent. The memory leakage is detected when

I close the application after running the for-loop. When you shut down the application a

window pops up with a long list of leaked memory blocks. Anyway, the problem is solved.

The leakage disappeared when I changed Value.GetText to Value.Text in the statement

 

TFile.WriteAllText(CSVFile, Value.GetText, Encoding);

inside the for-loop. Apparently, the expression Value.GetText is what caused the memory leaks.

Sorry for my sloppy posts.

Share this post


Link to post

Yes, but what is reporting the memory leak? There are lots of leak detection tools. If you use full fastmm then you can get allocation stack traces. 

 

It doesn't sound like you've really understood the issue. Normally Text would just map directly to GetText. But we still have no idea what Value is. 

 

This thread displays a deeper problem. That you think we can tell you what is happening with such incomplete details highlights the fact that you are also trying to solve the problem without those details. 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×