|
Rg i have a same proble.Did you find solution?
|
|
|
|
|
Hey,
I have the same problem with you. How did u solved this problem eventually?
thx.
|
|
|
|
|
could you please tell me how to sort a numeric column in excel automation.
thanks in advance,
Anandi
|
|
|
|
|
how to fix it
You Suffer,But Why?
|
|
|
|
|
Hi,
Is there a simple possibility to implement insert/delete functions for a row/column?
regards,
Ilko
|
|
|
|
|
Your code help me so much , thank you~~
|
|
|
|
|
I used your class and I think it's a very good one, thank you!
|
|
|
|
|
It's really give me a big favor
than you very much
|
|
|
|
|
I am not able to use the above code with windows mobile 5.0.. it is not able to open the file...! any way out of this??
|
|
|
|
|
Hi Yap,
Thank you for your work! I never thought that it is possible to get such class in C++.
When I run a couple of tests I noticed that percentages the value which is read form Excel is treated incorrectly. I was testing on MS Excel 2003. When I typed for example "56%" in a cell
Your implementation returned to me "0.56". For "5666%" i saw "56.66" as output. I don't thing this is correct behavior - I think that user expects to see exactly the same data which he or she had typed in a cell. What do You think about this?
In method "GetDoubleFromRKValue" I can see that there is a multiplication of "doublevalue_" on .01. But I can't find any reasons which can explain this. This is why I'm disturbing you. Can you shed some light on it? What is this multiplication is for? arithmetic overflow?
Thanks again for your work.
Kind regards, Eugene.
|
|
|
|
|
0.56 is the correct value for a cell containing 56%. How excel displays the value .56 is a formatting option, it does not change the actual value of the cell.
|
|
|
|
|
i've tried to use "BasicExcelVC6.cpp" and "BasicExcelVC6.hpp". And my data contains 2110 rows and 2 columns. The first column is a string data type, e.g. 20040103 (which means a date, but i changed it to general/string/integer, since BasicExcel class cannot read date 2004/1/3), and the second column is a double data type, e.g. 9144.65. Here are my trials:
1) I used the same one like in the demo
switch (cell->Type())
{
case BasicExcelCell::UNDEFINED:
printf(" ");
break;
case BasicExcelCell::INT:
printf("%10d", cell->GetInteger());
break;
case BasicExcelCell::DOUBLE:
printf("%10.6lf", cell->GetDouble());
break;
case BasicExcelCell::STRING:
printf("%10s", cell->GetString());
break;
case BasicExcelCell::WSTRING:
wprintf(L"%10s", cell->GetWString());
break;
}
And the result that i had is the first column data is got as BasicExcelCell::INT (no wonder about these, because it contains something like "20040103"); but some of the second column data is got as BasicExcelCell::INT, even if the data is something like "9144.65" (there's no quotation, it's just to emphasize the data). From 2110 rows of second column data, i've got 757 data of integers and 1353 data of doubles. I wonder why it could be like that?
2) I use code like
double tempDouble = 0;
if ( cell->Get(tempDouble) )
{
counterDouble++;
printf( "%10.2lf", tempDouble );
}
In this code, i've got 2110 data of doubles, but when i saw the printed tempDouble, i've got missing floating point for some of them like in the first one, e.g. 9144.65 will be printed as 9144.
Does anyone have any issues something like me? Thank you for your attention. I will wait for your reply.
PS: If my data is 2034.00, is it possible to be defined as double?
modified on Wednesday, October 1, 2008 4:58 AM
|
|
|
|
|
Hi,
I'm trying to use your excellant basciexcel class. I appreciate all the work you put into it.
The demo compiles and runs fine in .net 2005. .xls produced reads in excel ok.
When I incorporate this into my project and do simple things, the file it creates gets 'locked' and is not sharable when the app closes. If I try and run it, excel crashes and a base copy of it continues to run, must be killed with task manager. Looking at it with a binary editor, does not show anything really wrong... It looks like some minimum sequence of cells/rows must be created to produce a basic file. Is this the case?
Os is win2k.
Any idea what is going on here?
Thanks in advance if you get the time to look at it
ken
|
|
|
|
|
Hello,
nice usable classed code, thank you...
If memory sufficed, I think, large files would open, but I try to open a file consisting of 65535 lines and 17 columns (9,3 mb) and the error arises here:
void CompoundFile::GetBlockIndices(size_t startIndex, vector<size_t>& indices, bool isBig)
{
indices.clear();
if (isBig)
{
}
else
{
for (size_t i=startIndex; i!=-2; i=sblocksIndices_[i]) indices.push_back(i);
}
}</size_t>
i think this problem in LoadBAT() function, which loading incorrect values into vector blocksIndices...
Have you any decisions ?
i can send my xls file to email, give me address...
modified on Monday, September 22, 2008 3:36 AM
|
|
|
|
|
Have You ever fixed this BUG?
|
|
|
|
|
Have you solve this problem yet? I get the same problem. I think this is caused by LoadBAT(),in
{for (size_t i=0; i<header_.XBATCount_; ++i)
{
blocksIndices_.resize(blocksIndices_.size()+128, -1);
file_.Read(header_.XBATStart_+i+1, &*(block_.begin()));
for (size_t j=0; j<128; ++j)
{
LittleEndian::Read(&*(block_.begin()), blocksIndices_[j+((i+109)*128)], j*4, 4);
}
}}
read XBAT is different with read BAT.And in read BAT,
for (size_t i=0; i<header_.BATCount_; ++i)
the BAT only have 109 block.
|
|
|
|
|
Hello~
There are several wcstombs function to convert wide char to ASCII.
but the UTF16LE filename will be corrupt after the mcstombs function if the filename has a non-ascii code.
Therefore, SaveAs function does not work if the destination path has non-ascii character.
because not only "file_.open(char filename , ...." but also "file_.open(wchar_t filename, ...." works,
I think there is no need to convert wchar_t to char by wcstombs. It just result in a failure if the path includes non-ascii letters.
|
|
|
|
|
I have met same problem SaveAs
But in some situations, path often includes non-ascii chars, (chinese, japanese etc).
so i think the best idea is call setlocale according to os's language setting. some funcs like Block::Create(const wchar_t* filename) use filenameLength+1 as the length of converted asciii string is incorrect . it need be calculated or simply using MAX_PATH has less risk.
Good good study, day day up
|
|
|
|
|
i do a project where i need to be able to open a excel file and then write a value into the next free row but if i use following code my compiler cant cope with it:
BasicExcel e;
BasicExcelWorksheet* sheet;
BasicExcelCell* Cell;
e.Load(date_m_y);
sheet = e.GetWorksheet("sheet");
row = sheet->GetTotalRows();
sheet->Cell(row-1,1)->SetInteger(hour);
sheet->Cell(row-1,2)->SetInteger(day);
sheet->Cell(row-1,4)->SetDouble(strom_h);
sheet->Cell(row-1,5)->SetDouble(strom_d);
sheet->Cell(row-1,6)->SetDouble(strom_y);
e.Save();
actually the compiler says: untreated exception at 0x000bc8c2 in project.exe 0xC0000005: accessviolation while reading at position 0x0000000c.
i'd be glad if somebody could help me as fast as possible
|
|
|
|
|
I'am using Visual C++ 6.0 and BasicExcelV6 in a Projekt, reading many Excelfiles step by step, only one at a time. I get an:
First-chance exception in CCSDis.exe: 0xC0000005: Access Violation.
on line:
retVal |= ((wchar_t)((unsigned char)buffer[pos+i])) << 8*i;
in the Method:
LittleEndian::Read
Interesting by using:
YExcel::BasicExcel *e;
e = new YExcel::BasicExcel;
delete e;
I can read only 3 Sheets using:
YExcel::BasicExcel e;
I can Read 20 or so.
Reading for 100 times the same File, no Error.
(Not in a loop, For every File this procedure is called new, a new Class is defined, a new Load is called)
Need an BasicExcel.Unload to cleanup?
modified on Friday, September 12, 2008 6:39 AM
|
|
|
|
|
After some investigation I font some Errors?
like:
static void ReadString(const char* buffer, wchar_t* str, int pos=0, int bytes=0)
{
for (int i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*SIZEOFWCHAR_T);
}
If I understand it correct, get a Buffer of X Bytes, and Read X*2 Bytes (SIZEOFWCHAR_T) which must result in a
violation any way. I can't change it, becouse I don't know what is correct, 1 Byte or 2 Byte Chars.
|
|
|
|
|
Looks it works if you change
for (int i=0; i<bytes; ++i) Read(buffer, str[i], pos+i*SIZEOFWCHAR_T);
to
for (int i=0; i<bytes; ++i) Read(buffer, str[i], pos+i);
But I only Read Files, i think you must also change in BasicExcelV6.hpp
for (int i=0; i<bytes; ++i) Write(buffer, str[i], pos+i*SIZEOFWCHAR_T);
to
for (int i=0; i<bytes; ++i) Write(buffer, str[i], pos+i);
I'am not shure, check it out, if you have some Troubles with Violations, or Strings
|
|
|
|
|
Forget it, the Library still overwrites internal Memory.
Give up, and search an other way for it.
|
|
|
|
|
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)
{
...
}
|
|
|
|
|