|
HI, I met the same problem.
I'am using Visual C++ 9.0. When I try to open a file consisting of 6 tables, 5 or 6 columns every table and 4000 lines totally, I get an :
Debug Assertion Failed!
Program: ...
File: d:\program files\microsoft visual studio 9.0\vc\include\vector
Line: 764
Expression: vector subscript out of range
I press Retry to debug the application. The imformation in Call Stack:
xxx.exe!std::_Debug_message(const wchar_t * message=0x011d9208, const wchar_t * file=0x011d9250, unsigned int line=764) Line 24 C++
xxx.exe!std::vector<char,std::allocator<char> >::operator[](unsigned int _Pos=83685) Line 764 + 0x14 bytes C++
xxx.exe!YCompoundFiles::LittleEndian::Read<unsigned int>(const std::vector<char,std::allocator<char> > & buffer=[83451](-30,17 '',0,0,114 'r',16 '',0,0,1 '
',0,0,75 'K',2 '',0,1 '
',-94,91 '[',102 'f',-113,3 '',0,0,75 'K',49 '1',49 '1',6 '',0,1 '
',39 ''',89 'Y',-117,87 'W',110 'n',102 'f',26 '',-112,-94,91 '[',102 'f',-113,3 '',0,0,75 'K',49 '1',50 '2',6 '',0,1 '
',39 ''',89 'Y',-117,87 'W',-52,83 'S',66 'B',92 '\',-94,91 '[',102 'f',-113,3 '',0,0,75 'K',49 '1',51 '3',6 '',0,1 '
',39 ''',89 'Y',...,...), unsigned int & retVal=0, int pos=83685, int bytes=2) Line 150 + 0xf bytes C++
xxx.exe!YExcel::Workbook::SharedStringTable::Read(const char * data=0x035d9ff9) Line 3108 + 0x16 bytes C++
xxx.exe!YExcel::Workbook::Read(const char * data=0x035d6cf8) Line 2820 + 0x20 bytes C++
xxx.exe!YExcel::BasicExcel::Read(const char * data=0x035d6cf8, unsigned int dataSize=438676) Line 4877 + 0x15 bytes C++
xxx.exe!YExcel::BasicExcel::Load(const char * filename=0x035d3888) Line 4505 + 0x42 bytes C++
In LittleEndian::Read method, the app stoped on line :
retVal |= ((Type)((unsigned char)buffer[pos+i])) << 8*i;
In Workbook::SharedStringTable::Read method, the app stoped on line:
LittleEndian::Read(data_, stringSize, npos, 2);
I'm trying to resolve this bug, thanks for any suggestion .
|
|
|
|
|
Maybe, I have found the answer .
Fisrt, let's look at two member variables's data of class YExcel::Record.
The data in continueIndices_[10]
[0] 8213 unsigned int
[1] 16433 unsigned int
[2] 24654 unsigned int
[3] 32874 unsigned int
[4] 41098 unsigned int
...
The data in data_[83451]
...
[32874] 2 '' char
[32875] 0 char
[32876] 5 '' char
[32877] 16 '' char
[32878] 0 char
[32879] 0 char
[32880] 0 char
[32881] 71 'G' char
[32882] -106 char
[32883] -65 char
[32884] 83 'S' char
...
data_[32874] is a Continue Indices (What's that? ), and is begining of a string data at the same time. So when npos = 32874, the app will go to strings_[i].ContinueRead , not strings_[i].Read in SharedStringTable::Read method.
Here is SharedStringTable::Read method.
size_t Workbook::SharedStringTable::Read(const char* data)
{
Record::Read(data);
LittleEndian::Read(data_, stringsTotal_, 0, 4);
LittleEndian::Read(data_, uniqueStringsTotal_, 4, 4);
strings_.clear();
strings_.resize(uniqueStringsTotal_);
size_t npos = 8;
if (continueIndices_.empty())
{
for (size_t i=0; i<uniqueStringsTotal_; ++i)
{
npos += strings_[i].Read(&*(data_.begin())+npos);
}
}
else
{
size_t maxContinue = continueIndices_.size();
for (size_t i=0, c=0; i<uniqueStringsTotal_; ++i)
{
char unicode;
size_t stringSize;
LittleEndian::Read(data_, stringSize, npos, 2);
LittleEndian::Read(data_, unicode, npos+2, 1);
size_t multiplier = unicode & 1 ? 2 : 1;
if (c >= maxContinue || npos+stringSize*multiplier+3 <= continueIndices_[c])
{
npos += strings_[i].Read(&*(data_.begin())+npos);
}
else
{
...
if (stringSize>0)
{
bytesRead += strings_[i].ContinueRead(&*(data_.begin())+npos+bytesRead, stringSize);
}
npos += bytesRead;
}
}
}
return npos + 4*(npos/8224 + 1);
}
Here is LargeString::ContinueRead .
size_t LargeString::ContinueRead(const char* data, size_t size)
{
if (size == 0) return 0;
char unicode;
LittleEndian::Read(data, unicode, 0, 1);
if (unicode_ == -1) unicode_ = unicode;
if (unicode_ & 1)
{
size_t npos = 1;
if (richtext_) npos += 2;
if (phonetic_) npos += 4;
size_t strpos = wname_.size();
wname_.resize(strpos+size, 0);
if (unicode & 1)
{
LittleEndian::ReadString(data, &*(wname_.begin())+strpos, npos, size);
npos += size * SIZEOFWCHAR_T;
}
else
{
...
}
if (richtext_) npos += 4*richtext_;
if (phonetic_) npos += phonetic_;
return npos;
}
else
...
}
In LargeString::ContinueRead method, phonetic isn't be readed and processed, data_[32877] is readed as string, that's the beginning of misdata.
I have added some code in ContinueRead and fixed this bug, maybe not a best way.
size_t LargeString::ContinueRead(const char* data, size_t size)
{
if (size == 0) return 0;
char unicode;
LittleEndian::Read(data, unicode, 0, 1);
if (unicode_ == -1) unicode_ = unicode;
size_t npos = 1;
if (unicode_ & 8)
{
LittleEndian::Read(data, richtext_, npos, 2);
npos += 2;
}
if (unicode_ & 4) {
LittleEndian::Read(data, phonetic_, npos, 4);
}
if (unicode_ & 1)
{
...
}
|
|
|
|
|
Hello,
I have the same problem. I try the solutions gaves on the retry, but it doesn't work.
I think i found a good way to resolve the problem : I just delete the define of the define UTF16 on line 60 in the file hpp.
#define UTF16
to
//#define UTF16
It works !
Sorry for my poor english (I have an excuse, I'm french o )
Good look
Nota : Very interresting class !
|
|
|
|
|
Hi,
i have MS-Visual studio 2006.
n i opened your file in a new win32 console application(empty project).
even though i added these file in appropriate Source n header files,
I m unable to even compile it. it gives me error like basicexcel.hpp not found.
can anyone pls help me out.
Appreciate any comment.
Ahmer
|
|
|
|
|
Thank your source code, very thank!!
But, I have a question??
This BasicExcle can not open *.csv file
Can you add the function to help me.
Thank You!!
|
|
|
|
|
Hi im new to excel automation... I just want to ask if it is possible to embed Excel to MFC? thanks a lot
|
|
|
|
|
#include "stdafx.h" // default class
#include "ExcelMFC.h" //MFC class for this program which u created
#include "ExcelMFCDlg.h" //MFC dialog class for ur dialog file
#include "BasicExcelVC6.hpp" //n ur include file
basically include all the necessary file in all of the .cpp file....
mainly, stdafx.h & basicExcelVC6.hpp...
|
|
|
|
|
It's very easy to use and really usefull for me
thanks again~
|
|
|
|
|
This class works great. I have been fighting with C# Excel.OLB and Office version and could not get it work. This C++ codes works fine. But I cannot load a file when a sheet contains graphics. What's wrong ? Is there a trick like writing the excel file and adding an existing graphic sheet without really "loading" or processing the sheet with the graphic ? I am using Excel 97.
|
|
|
|
|
When I call Save() to save the new wrote data several times(2, or more), the program will crash, and the memory corrupted. following is the code.
using namespace YExcel;
void CTestExcelApp::TestBasicExcel()
{
BasicExcel aLogFile;
BasicExcelWorksheet* apLogSheet;
aLogFile.New( 1 );
aLogFile.RenameWorksheet( "Sheet1", "PowerLog" );
apLogSheet = aLogFile.GetWorksheet( "PowerLog" );
if (apLogSheet)
{
apLogSheet->Cell(1,1->SetString("Time");
apLogSheet->Cell(1,2->SetString("Power");
apLogSheet->Cell(1,3->SetString("Unit");
}
aLogFile.SaveAs( "f:\\1.xls" );
for ( int i = 2; i < 600; i++ )
{
TRACE("%d\n", i-2 );
apLogSheet>Cell(i,6)->SetDouble( 1.0);
aLogFile.Save();
}
}
|
|
|
|
|
I do some investigation, found,
1) after the first time calling Save() or SaveAs(), as long as you access a cell beyond the previous cell matrix range, then call Save() will corrupt the memory.
eg.
apLogSheet->Cell(2,16)->SetString("Time");
aLogFile.SaveAs( "f:\\1.xls" );
apLogSheet->Cell(3,14)->SetString("Unit");
aLogFile.Save( );
aLogFile.Save( );
btw, if use SaveAs(), the "death" will be later.
wish heplful for fixing the bug
|
|
|
|
|
Hi All!
Problem in Subject
Respect for any ideas to solve this
|
|
|
|
|
I tried bringing this in to an MFC dialog app and all hell broke loose. Thirty errors just trying to compile BasicExcel.h
Has anyone succesfully built a dialog app using this class?
Thank you in advance
Pierre
|
|
|
|
|
Yes I have.
Just add stdafx.h in the BasicExcelVC6.hpp and in BasicExcelVC6.cpp file and that's all
Mauricio Alfaro
|
|
|
|
|
How could we delete a specified row, and how do we set the style of some row e.g color
|
|
|
|
|
I'm using the BasicExcel program & get the following compiler error :
C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\cstdio(17): error C2143: syntax error : missing '{' before ':'
This occurs for every using declaration like :
using ::size_t;
I've heard this may be due to the program written in C but being compiled in C++ - how can I resolve this problem ?
Thanks,
ak
|
|
|
|
|
size_t corresponds to the integral data type returned by the language operator sizeof and is defined in the <cstddef>header file (among others) as an unsigned integral type.It expresses a size or count in bytes.
|
|
|
|
|
Hi,
I downloaded the BasicExcel files. I created a project in VC++ where I have included BasicExcel.hpp in the Header Files folder & BasicExcel.cpp in the Source Files folder. I also have my own file test.c as a seperate file in the Source Files folder.
When I build the solution I get error :
C:\test.c(10): fatal error C1083: Cannot open include file: 'BasicExcel.hpp': No such file or directory
Am I linking this hpp file incorrectly ?
My program is just a copy of the YExcel.cpp :
#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <basicexcel.hpp>
using namespace YExcel;
int main(int argc, char* argv[])
{
BasicExcel e;
// Load a workbook with one sheet, display its contents and save into another file.
e.Load("tester.xls");
BasicExcelWorksheet* sheet1 = e.GetWorksheet("Sheet1");
if (sheet1)
{
size_t maxRows = sheet1->GetTotalRows();
size_t maxCols = sheet1->GetTotalCols();
cout << "Dimension of " << sheet1->GetAnsiSheetName() << " (" << maxRows << ", " << maxCols << ")" << endl;
}
}
Any suggestions would be greatly appreciated.
Thanks,
ak
|
|
|
|
|
rename .hpp to .h and change the precompiler settings
|
|
|
|
|
change test.c to test.cpp.
|
|
|
|
|
change #include <basicexcelvc6.hpp>
to #include "BasicExcelVC6.hpp"
i had the same prob... n it resolved my prob...
|
|
|
|
|
First, let me say thanks for the code; it helps me out quite a bit.
Now to the problem. When opening an Excel file which contains data in rows > 32768, the app could experience exceptions. Specifically, in BasicExcelWorksheet::UpdateCells() when it is getting the Row Index via rCellBlocks[j].RowIndex(), then using that value as an index into the vector, the exception can occur. For example:
1. Create an Excel workbook with some text in Row 32769, Col A. Save file.
2. Open it with the BasicExcelWorksheet class via the Load() method.
3. In BasicExcelWorksheet::UpdateCells(), rCellBlocks[j].RowIndex() returns -32768 [notice that it is negative].
4. In BasicExcelWorksheet::UpdateCells(), in the "case CODE::LABELSST:" section, it sets the value with the following call:
cells_[row][col].Set(&*(str.begin()));
The actual row index value is 32768 (0x8000) but when returned by Row() and converted into the "size_t row" variable, it then becomes 0xFFFF8000 (same as -32768). Now the problem becomes more clear because accessing the cells_ vector with a negative index (or a really large index if you think of 0xFFFF8000 as unsigned) is likely to cause an exception. Or if you treat that value as unsigned, 0xFFFF8000 is 4294934528 which means we need a really really big vector.
Essentially, the above statement becomes one of these (all of which look bad to me):
cells_[0xFFFF8000][0].Set(&*(str.begin()));
cells_[4294934528][0].Set(&*(str.begin()));
cells_[-32768][0].Set(&*(str.begin()));
This is what is causing an exception for me.
There are a few things to consider when addressing this issue:
- the Row() method should probably return "unsigned short" instead of "short". Perhaps it could be "unsigned long" to allow for future versions which might support > 64K rows.
- "size_t row" could be changed to "unsigned short" but might not be necessary if the Row() method is changed.
- Col() is probably OK since the limit on columns still seems to be 16K, however, it probably wouldn't hurt to make it "unsigned short" too.
Thanks,
Scott.
|
|
|
|
|
Hi,
Just wanted to thank you for this code... I am using it in a company project and this has made my job so much easier... thanks again...
regards,
hsalihbA
|
|
|
|
|
I think this class is fantastic. Thank you to the author!
I have written some code to create an 8 column spreadsheet XLS file.
However the column sizes are all the same. They look like defaults. Is it possible to resize the columns?
|
|
|
|
|
hi,
I am trying to read the date from excel file using this class, it returns the value of date cell in double (GetDouble()).
I am unable to understand the format of date. As example if date is stored 24/3/2007 in excel i got the vaule in a variable of type double as 32982.
Please guide me...
Umar
|
|
|
|
|