InsertRows throwing out Name Definition range

Questions and answers on how to use XLSReadWriteII 5.
Post Reply
Dmeade
Posts: 26
Joined: Tue Jul 16, 2013 7:22 am

InsertRows throwing out Name Definition range

Post by Dmeade »

I'm using XLS RW Component Version 5.20.44

If you Create a name that has a range
then insert lines inside that range
the range is not updating properly when using XLSRW.Version = xvExcel2007


if you are working with XLSRW.Version = xvExcel97 it seems to be ok

i suspect that this is the problem

name "NAMETEST" Definition
Before Insert "Sheet1!$D$1:$D$2"
After Insert "Sheet1!$D$1:$D3" <<---- Missing the $3

when you open the XLSX file with Microsoft Excel 2013
the sum(NAMETEST) column is not working correctly

Here is code to reproduce this issue

Unit XLSTestRun

Code: Select all

unit XLSTestRun;

interface
uses Xc12Utils5, XLSReadWriteII5, XLSNames5, SysUtils, typinfo, Vcl.Dialogs;

const EXPECTED_NAME_DEFINITION_VALUE = 'Sheet1!$D$1:$D$3';

procedure XLSNameTest( XLSVersion : TExcelVersion; sFilename : String ) ;

implementation

procedure XLSNameTest( XLSVersion : TExcelVersion; sFilename : String );
  var XLSReadWriteII52: TXLSReadWriteII5;
    Nme : TXLSName;
    dCellE5DefinitionValue, dCellF5DefinitionValue : String;
    Procedure ShowAMessage(sString : String);
    var sMessage : String;
    begin
      sMessage := 'XLS.Version = ' +  GetEnumName(TypeInfo(TExcelVersion), Ord(XLSVersion))  + sLineBreak +
                  'XLS.FileName = "'+sFilename+'"'  + sLineBreak +
                  sString ;
      ShowMessage( sMessage );
    end;
begin
  XLSReadWriteII52 := TXLSReadWriteII5.Create(nil);
  XLSReadWriteII52.Version := XLSVersion;
  XLSReadWriteII52.Filename := sFilename;

  try
    XLSReadWriteII52.Write;
    assert( FileExists( XLSReadWriteII52.Filename ) , 'File not Created. "'+ XLSReadWriteII52.Filename +'"');

    XLSReadWriteII52.Sheets[0].AsString[0,0] := 'START';
    XLSReadWriteII52.Sheets[0].AsFloat[3,0]  := 1.0;
    XLSReadWriteII52.Sheets[0].AsString[0,1] := 'END';
    XLSReadWriteII52.Sheets[0].AsFloat[3,1]  := 2.0;

    XLSReadWriteII52.names.Add( 'NAMETEST', 'Sheet1!$D$1:$D$2' );

    XLSReadWriteII52.Write;
    XLSReadWriteII52.Sheets[0].AsString[0,3] := 'Sum Test';
    XLSReadWriteII52.Sheets[0].AsFormula[3,3] := 'Sum(D1:D2)';

    Nme := XLSReadWriteII52.Names.Find( 'NAMETEST' );
    if Nme = nil then begin
      raise exception.Create( 'XLS Name "NAMETEST" not Found');
    end;

    XLSReadWriteII52.Sheets[0].AsFormula[4,3] := 'Sum(NAMETEST)';

    XLSReadWriteII52.InsertRows( 0, 1, 1 );

    XLSReadWriteII52.Sheets[0].AsString[0,1] := 'INSERTED ROW';
    XLSReadWriteII52.Sheets[0].AsFloat[3,1]  := 1.1;
    XLSReadWriteII52.Write;

    XLSReadWriteII52.names.Add( 'NAMETEST2', 'Sheet1!$D$1:$D$3' );
    XLSReadWriteII52.Sheets[0].AsFormula[5,4] := 'Sum(NAMETEST2)';
    XLSReadWriteII52.Write;

    XLSReadWriteII52.Calculate;

    XLSReadWriteII52.Write;

    Nme := XLSReadWriteII52.Names.Find( 'NAMETEST' );
    if Nme = nil then begin
      raise exception.Create( 'XLS Name "NAMETEST" not Found');
    end else begin
      dCellE5DefinitionValue := Nme.Definition;
      if dCellF5DefinitionValue <> EXPECTED_NAME_DEFINITION_VALUE then
        ShowAMessage( 'name "NAMETEST" Definition was "'+ dCellE5DefinitionValue +'" Expected "'+ EXPECTED_NAME_DEFINITION_VALUE +'"'  )
    end;

    Nme := XLSReadWriteII52.Names.Find( 'NAMETEST2' );
    if Nme = nil then begin
      raise exception.Create( 'XLS Name "NAMETEST2" not Found');
    end else begin
      dCellF5DefinitionValue := Nme.Definition;
      if dCellF5DefinitionValue <> EXPECTED_NAME_DEFINITION_VALUE then
        ShowAMessage( 'name "NAMETEST2" Definition was "'+ dCellF5DefinitionValue +'" Expected "'+ EXPECTED_NAME_DEFINITION_VALUE +'"'  )
    end;
  finally
    XLSReadWriteII52.Free;
  end;
end;

end.
calling the unit

Code: Select all

procedure TForm7.btn3Click(Sender: TObject);
var slTests : TStringList;
begin
   XLSNameTest(xvExcel97, IncludeTrailingPathDelimiter( ExtractFilePath(Application.exename) ) +
                                          'XLSTestV97' + FormatDateTime('yymmdd_hhnnss_zzz', now) + '.XLS' );
   XLSNameTest(xvExcel2007, IncludeTrailingPathDelimiter( ExtractFilePath(Application.exename) ) +
                                          'XLSTestV2007' + FormatDateTime('yymmdd_hhnnss_zzz', now) + '.XLSX' );

end;
Let me know if you have any Questions
Last edited by Dmeade on Thu Apr 09, 2015 2:54 am, edited 1 time in total.
larsa
Site Admin
Posts: 926
Joined: Mon Jun 27, 2005 9:30 pm

Re: InsertRows throwing out Name Definition

Post by larsa »

Hello

This is fixed in update 5.20.45
Lars Arvidsson, Axolot Data
Dmeade
Posts: 26
Joined: Tue Jul 16, 2013 7:22 am

Re: InsertRows throwing out Name Definition

Post by Dmeade »

Hi

i got version 5.20.45

and it was working with the original example code i posted
however when working with multiple sheets it didn't seem to work properly
xvExcel97 - didnt seem to link up the sheets propely
xvExcel2007 - didnt update the name range when the rows were inserted on another sheet

e.g.

Code: Select all

unit XLSTestRun2;

interface
uses Xc12Utils5, XLSReadWriteII5, XLSNames5, SysUtils, typinfo, Vcl.Dialogs;

procedure XLSNameTest2( XLSVersion : TExcelVersion; sFilename : String ) ;

implementation

procedure XLSNameTest2( XLSVersion : TExcelVersion; sFilename : String ) ;
var Sheet1Name, Sheet2name, Sheet3Name : String;
    XLSReadWriteII52: TXLSReadWriteII5;
begin
  XLSReadWriteII52 := TXLSReadWriteII5.Create(nil);
  XLSReadWriteII52.Version := XLSVersion;
  XLSReadWriteII52.Filename := sFilename;

  try
    XLSReadWriteII52.Write;
    assert( FileExists( XLSReadWriteII52.Filename ) , 'File not Created. "'+ XLSReadWriteII52.Filename +'"');

    Sheet1Name := 'Summary';
    Sheet2Name := 'SomeStuff';
    Sheet3Name := 'OtherStuff';

    XLSReadWriteII52.Add;
    XLSReadWriteII52.Add;

    XLSReadWriteII52.Sheets[0].Name := Sheet1Name;
    XLSReadWriteII52.Write;
    XLSReadWriteII52.Sheets[1].Name := Sheet2Name;
    XLSReadWriteII52.Write;
    XLSReadWriteII52.Sheets[2].Name := Sheet3Name;
    XLSReadWriteII52.Write;

    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,0] := 0;
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,1] := 1;
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,2] := 2;
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,3] := 3;
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,4] := 4;

    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,0] := 5;
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,1] := 6;
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,2] := 7;
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,3] := 8;
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,4] := 9;

    XLSReadWriteII52.Write;
    XLSReadWriteII52.read;

    XLSReadWriteII52.names.Add( Sheet2Name + '_NAME', Sheet2Name+'!$A$1:$A$5' );
    XLSReadWriteII52.names.Add( Sheet3Name + '_NAME', Sheet3Name+'!$A$1:$A$5' );
    XLSReadWriteII52.Write;

    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFormula[0,11] := 'Sum('+ Sheet2Name + '_NAME' +')';
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFormula[1,11] := 'Sum(A1:A5)';

    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFormula[0,11] := 'Sum('+ Sheet3Name + '_NAME' +')';
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFormula[1,11] := 'Sum(A1:A5)';

    XLSReadWriteII52.SheetByName( Sheet1Name ).AsString[0,0] := Sheet2Name+ ' Totals';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[3,0] := 'Sum('+ Sheet2Name + '_NAME' +')';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[4,0] := 'SUM('+Sheet2Name+'!A1:A6)';

    XLSReadWriteII52.SheetByName( Sheet1Name ).AsString[0,1] := Sheet3Name+ ' Totals';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[3,1] := 'Sum('+ Sheet3Name + '_NAME' +')';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[4,1] := 'SUM('+Sheet3Name+'!A1:A6)';

    XLSReadWriteII52.calculate;
    XLSReadWriteII52.Write;

    XLSReadWriteII52.SheetByName( Sheet2Name ).InsertRows(1,1);
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0, 1] := 100;
    //XLSReadWriteII52.SheetByName( Sheet3Name ).InsertRows(1,1);
    XLSReadWriteII52.InsertRows( XLSReadWriteII52.SheetByName( Sheet3Name ).Index, 1, 1  );
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0, 1] := 200;

    XLSReadWriteII52.Write;
  finally
    XLSReadWriteII52.Free;
  end;
end;

end.

Code: Select all

uses ShellApi, XLSTestRun2;

Code: Select all

procedure TForm7.btn4Click(Sender: TObject);
var sExportLocation : String;
begin

  sExportLocation := IncludeTrailingPathDelimiter( ExtractFilePath(Application.exename) ) +
                                          'XLSTestV97' + FormatDateTime('yymmdd_hhnnss_zzz', now) + '.XLS';
  XLSNameTest2(xvExcel97, sExportLocation );

  ShellExecute(self.Handle, 'Open', PChar(sExportLocation), PChar(''), nil, 1);

  sExportLocation := IncludeTrailingPathDelimiter( ExtractFilePath(Application.exename) ) +
                                          'XLSTestV2007' + FormatDateTime('yymmdd_hhnnss_zzz', now) + '.XLSX' ;
  XLSNameTest2(xvExcel2007, sExportLocation);


  ShellExecute(self.Handle, 'Open', PChar(sExportLocation), PChar(''), nil, 1);

end;

let me know if you have any questions
Dmeade
Posts: 26
Joined: Tue Jul 16, 2013 7:22 am

Re: InsertRows throwing out Name Definition

Post by Dmeade »

Hi Again

i think i have narrowed down the issue

if you insert a line on the first sheet everything seems to recalculate OK
if you insert lines only on sheet 2 the names are not having their range updated

if you enable the code below - the names are being recalculated ok

Code: Select all

//XLSReadWriteII52.SheetByName( Sheet1Name ).InsertRows(1,1);
//XLSReadWriteII52.SheetByName( Sheet1Name ).AsFloat[0, 1] := 10;
here is the code to reproduce

Code: Select all

unit XLSTestRun2;

interface
uses Xc12Utils5, XLSReadWriteII5, XLSNames5, SysUtils, typinfo, Vcl.Dialogs;

procedure XLSNameTest2( XLSVersion : TExcelVersion; sFilename : String ) ;

implementation

procedure XLSNameTest2( XLSVersion : TExcelVersion; sFilename : String ) ;
var Sheet1Name, Sheet2name, Sheet3Name : String;
    name1, Name2, name3 : String;
    XLSReadWriteII52: TXLSReadWriteII5;
begin
  XLSReadWriteII52 := TXLSReadWriteII5.Create(nil);
  XLSReadWriteII52.Version := XLSVersion;
  XLSReadWriteII52.Filename := sFilename;

  try
    XLSReadWriteII52.Write;
    assert( FileExists( XLSReadWriteII52.Filename ) , 'File not Created. "'+ XLSReadWriteII52.Filename +'"');

    Sheet1Name := 'Summary';
    Sheet2Name := 'Some Stuff';
    Sheet3Name := 'OtherStuff';

    XLSReadWriteII52.Add;
    XLSReadWriteII52.Add;

    XLSReadWriteII52.Sheets[0].Name := Sheet1Name;
    XLSReadWriteII52.Write;
    XLSReadWriteII52.Sheets[1].Name := Sheet2Name;
    XLSReadWriteII52.Write;
    XLSReadWriteII52.Sheets[2].Name := Sheet3Name;
    XLSReadWriteII52.Write;

    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFloat[0,0] := 0;
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFloat[0,1] := 1;
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFloat[0,2] := 2;
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFloat[0,3] := 3;
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFloat[0,4] := 4;

    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,0] := 5;
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,1] := 6;
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,2] := 7;
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,3] := 8;
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0,4] := 9;

    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,0] := 10;
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,1] := 11;
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,2] := 12;
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,3] := 13;
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0,4] := 14;

    XLSReadWriteII52.Write;
    XLSReadWriteII52.read;

    name1 := StringReplace( Sheet1Name, ' ', '_', [rfReplaceAll, rfIgnoreCase] ) + '_NAME';
    Name2 := StringReplace( Sheet2Name, ' ', '_', [rfReplaceAll, rfIgnoreCase] ) + '_NAME';
    name3 := StringReplace( Sheet3Name, ' ', '_', [rfReplaceAll, rfIgnoreCase] ) + '_NAME';

    XLSReadWriteII52.names.Add( name1 , #39 + Sheet1Name + #39 +'!$A$1:$A$5' );
    XLSReadWriteII52.names.Add( name2 , #39 + Sheet2Name + #39 +'!$A$1:$A$5' );
    XLSReadWriteII52.names.Add( Name3 , #39 + Sheet3Name + #39 +'!$A$1:$A$5' );

    XLSReadWriteII52.Write;

    XLSReadWriteII52.SheetByName( Sheet1Name ).AsString[0,8] := 'Name';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsString[0,9] := 'Range';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[1,8] := 'Sum('+ Name1 +')';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[1,9] := 'Sum(A1:A5)';

    XLSReadWriteII52.SheetByName( Sheet2Name ).AsString[0,8] := 'Name';
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsString[0,9] := 'Range';
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFormula[1,8] := 'Sum('+ name2 +')';
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFormula[1,9] := 'Sum(A1:A5)';

    XLSReadWriteII52.SheetByName( Sheet3Name ).AsString[0,8] := 'Name';
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsString[0,9] := 'Range';
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFormula[1,8] := 'Sum('+ Name3 +')';
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFormula[1,9] := 'Sum(A1:A5)';

    XLSReadWriteII52.SheetByName( Sheet1Name ).AsString[3,10] := 'Names';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsString[4,10] := 'Range';

    XLSReadWriteII52.SheetByName( Sheet1Name ).AsString[0,13] := Sheet1Name+ ' Totals';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[3,13] := 'Sum('+ Name1 +')';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[4,13] := 'SUM('+#39+Sheet1Name+#39+'!A1:A6)';

    XLSReadWriteII52.SheetByName( Sheet1Name ).AsString[0,11] := Sheet2Name+ ' Totals';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[3,11] := 'Sum('+ name2 +')';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[4,11] := 'SUM('+#39 +Sheet2Name+ #39+'!A1:A6)';

    XLSReadWriteII52.SheetByName( Sheet1Name ).AsString[0,12] := Sheet3Name+ ' Totals';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[3,12] := 'Sum('+ Name3 +')';
    XLSReadWriteII52.SheetByName( Sheet1Name ).AsFormula[4,12] := 'SUM('+#39+Sheet3Name+#39+'!A1:A6)';

    XLSReadWriteII52.calculate;
    XLSReadWriteII52.Write;

    //XLSReadWriteII52.SheetByName( Sheet1Name ).InsertRows(1,1);
    //XLSReadWriteII52.SheetByName( Sheet1Name ).AsFloat[0, 1] := 10;

    XLSReadWriteII52.SheetByName( Sheet2Name ).InsertRows(1,1);
    XLSReadWriteII52.SheetByName( Sheet2Name ).AsFloat[0, 1] := 100;

    XLSReadWriteII52.InsertRows( XLSReadWriteII52.SheetByName( Sheet3Name ).Index, 1, 1  );
    XLSReadWriteII52.SheetByName( Sheet3Name ).AsFloat[0, 1] := 1000;


    XLSReadWriteII52.Calculate;
    XLSReadWriteII52.Write;
  finally
    XLSReadWriteII52.Free;
  end;
end;

end.

Code: Select all

procedure TForm7.btn4Click(Sender: TObject);
var sExportLocation : String;
begin

  sExportLocation := IncludeTrailingPathDelimiter( ExtractFilePath(Application.exename) ) +
                                          'XLSTestV97' + FormatDateTime('yymmdd_hhnnss_zzz', now) + '.XLS';
  XLSNameTest2(xvExcel97, sExportLocation );

  ShellExecute(self.Handle, 'Open', PChar(sExportLocation), PChar(''), nil, 1);

  sExportLocation := IncludeTrailingPathDelimiter( ExtractFilePath(Application.exename) ) +
                                          'XLSTestV2007' + FormatDateTime('yymmdd_hhnnss_zzz', now) + '.XLSX' ;
  XLSNameTest2(xvExcel2007, sExportLocation);


  ShellExecute(self.Handle, 'Open', PChar(sExportLocation), PChar(''), nil, 1);

end;
larsa
Site Admin
Posts: 926
Joined: Mon Jun 27, 2005 9:30 pm

Re: InsertRows throwing out Name Definition range

Post by larsa »

Hello

I can't reproduce this. Areas are adjusted correct. Please make sure that you have the latest update installed.
Lars Arvidsson, Axolot Data
Dmeade
Posts: 26
Joined: Tue Jul 16, 2013 7:22 am

Re: InsertRows throwing out Name Definition range

Post by Dmeade »

i was running 5.20.45

5.20.47 works

Thanks
Post Reply