Main place for discussions about U++ cross platform development framework.
Hello all Do you have any program using Upp++ for Ole automation? (only windows). This serve to handle not only Office programs like Excel or Word but other like Catia 5. If it does exist it could be prepared as a class that may be added to Bazaar. Best regards Koldo
Hello all I am doing the job. Next week I expect to have the first sample of a basic class to handle Excel spreadsheets. Best regards Koldo
koldo wrote on Sat, 18 October 2008 15:02 Hello all I am doing the job. Next week I expect to have the first sample of a basic class to handle Excel spreadsheets. Best regards Koldo Cute. Have you succeeded? Mirek
Hello luzr Yes. I did some functions to handle Ole and a small demo filling an excel spreadsheet. As I did not see any answer about this I centered to other functions, but after that I wanted to do the job. Here I enclose you the public: side of the class declaration that is implemented. class MSSheet { public: MSSheet(); ~MSSheet(); bool AddSheet(); bool OpenSheet(String fileName); bool SetVisible(bool); bool SetValue(int row, int col, String value); String GetValue(int row, int col); bool FillRange(String range); bool SetSaved(bool); bool SaveAs(String fileName, String type = "excel"); void Quit(); }; I wanted to extend this class and to add other classes like MSText and Catia (to handle CAD program Dassault Catia V) as I know rather well the ole interface to them. I was wondering too if doing something similar with OpenOffice so with the same set of functions we could handle both programs. But it is not very easy so I wanted to go step by step. Best regards Koldo
koldo wrote on Sun, 09 November 2008 11:11 Hello luzr Yes. I did some functions to handle Ole and a small demo filling an excel spreadsheet. As I did not see any answer about this I centered to other functions, but after that I wanted to do the job. Here I enclose you the public: side of the class declaration that is implemented. class MSSheet { public: MSSheet(); ~MSSheet(); bool AddSheet(); bool OpenSheet(String fileName); bool SetVisible(bool); bool SetValue(int row, int col, String value); String GetValue(int row, int col); bool FillRange(String range); bool SetSaved(bool); bool SaveAs(String fileName, String type = "excel"); void Quit(); }; I wanted to extend this class and to add other classes like MSText and Catia (to handle CAD program Dassault Catia V) as I know rather well the ole interface to them. I was wondering too if doing something similar with OpenOffice so with the same set of functions we could handle both programs. But it is not very easy so I wanted to go step by step. Best regards Koldo Great job. Any plans makeing them public? Mirek
Hello luzr Well... after the SysInfo functions first version release and full test I will follow working with it. Best regards Koldo
Hello luzr After first batch of SysInfo I will have first batch of Automation functions ready on December including MSSheet and MSText. Best regards Koldo
Hello all Ole Automation status: - Access to MSOffice completed (Msc and MinGW tested) - Access to OpenOffice -- Using Ole: in progress --- This interface only works in Windows --- Expected to end in one week. Sorry for the delay -- Using UNO: stopped! --- This interface would work in Linux and Windows --- I have spent many hours but it is too hard for me! (HELP REQUESTED) Best regards Koldo
Hello all I am very happy to include in Bazaar the Automation library and a console demo. It handles OpenOffice Calc and Writer and Microsoft Excel and Word. I have prepared it thinking in simplicity. For example: OfficeDoc doc; if (OfficeDoc::IsAvailable("Open")) doc.Init("Open") else if (OfficeDoc::IsAvailable("Microsoft")) doc.Init("Microsoft") else return; doc.SetFont("Arial", 14); doc.SetBold(true); doc.WriteText("Hello all!"); doc.SetFont("Arial", 12); doc.SetBold(false); doc.SetItalic(true); doc.WriteText("\n\nNon me latet [To replace] nonnullos vestrum"); doc.Select(); doc.Replace("[To replace]", "replaced text"); doc.Print(); doc.SaveAs("FileDemo", "doc"); doc.Quit(); So with the same set of functions it manages OpenOffice and Microsoft Office transparently fo the programmer. The main classes declaration is like this: class OfficeSheet { public: OfficeSheet(); ~OfficeSheet(); static bool IsAvailable(String type); bool Init(char *type); bool AddSheet(bool visible); bool OpenSheet(String fileName, bool visible); bool SetValue(int col, int row, Value value); bool SetValue(String cell, Value value); Value GetValue(int col, int row); Value GetValue(String cell); bool Replace(Value search, Value replace); bool SetBold(int col, int row, bool bold); bool SetBold(String cell, bool bold); bool SetBold(bool bold); bool SetFont(int col, int row, String name, int size); bool SetFont(String cell, String name, int size); bool SetFont(String name, int size); bool Select(String range); bool Select(int fromX, int fromY, int toX, int toY); bool Select(); bool Print(); bool SaveAs(String fileName, String type = "xls"); bool Quit(); }; class OfficeDoc { public: OfficeDoc(); ~OfficeDoc(); static bool IsAvailable(char *program); bool Init(char *type); bool AddDoc(bool visible); bool OpenDoc(String fileName, bool visible); bool SetFont(String font, int size); bool SetBold(bool bold); bool SetItalic(bool italic); bool WriteText(String value); bool Select(); bool Replace(String search, String replace); bool Print(); bool SetSaved(bool); bool SaveAs(String fileName, String type = "doc"); bool Quit(); }; Unfortunately it only works in Windows (MinGW and MSC) using Ole Automation. As I have explained before the OpenOffice official interface called UNO has been too much for me until now. Best regards Koldo
Hello Koldo! Thank you for interesting OleAutomation. I tried to buid Automation demo console with MSC9 and have following errors: SysInfo.lib(SysInfo.obj) : error LNK2019: unresolved external symbol __imp__DeleteDC@4 referenced in function "bool __cdecl Window_SaveCap ture(long,class Upp::String)" (?Window_SaveCapture@@YA_NJVString@Upp@@@Z) SysInfo.lib(SysInfo.obj) : error LNK2019: unresolved external symbol __imp__DeleteObject@4 referenced in function "bool __cdecl Window_Sav eCapture(long,class Upp::String)" (?Window_SaveCapture@@YA_NJVString@Upp@@@Z) SysInfo.lib(SysInfo.obj) : error LNK2019: unresolved external symbol __imp__GetDIBits@28 referenced in function "bool __cdecl Window_SaveC apture(long,class Upp::String)" (?Window_SaveCapture@@YA_NJVString@Upp@@@Z) SysInfo.lib(SysInfo.obj) : error LNK2019: unresolved external symbol __imp__BitBlt@36 referenced in function "bool __cdecl Window_SaveCapt ure(long,class Upp::String)" (?Window_SaveCapture@@YA_NJVString@Upp@@@Z) SysInfo.lib(SysInfo.obj) : error LNK2019: unresolved external symbol __imp__SelectObject@8 referenced in function "bool __cdecl Window_Sav eCapture(long,class Upp::String)" (?Window_SaveCapture@@YA_NJVString@Upp@@@Z) SysInfo.lib(SysInfo.obj) : error LNK2019: unresolved external symbol __imp__CreateCompatibleBitmap@12 referenced in function "bool __cdecl Window_SaveCapture(long,class Upp::String)" (?Window_SaveCapture@@YA_NJVString@Upp@@@Z) SysInfo.lib(SysInfo.obj) : error LNK2019: unresolved external symbol __imp__CreateCompatibleDC@4 referenced in function "bool __cdecl Wind ow_SaveCapture(long,class Upp::String)" (?Window_SaveCapture@@YA_NJVString@Upp@@@Z) C:\upp\out\MSC9.Force_size.Mt\Automation demo console.exe : fatal error LNK1120: 7 unresolved externals With GCC MINGW have not errors and works fine!
Hello tojocky All the functions not found by the linker are in gdi32.lib so it seems the compiler does not found it for MSC. Please check if in "Build methods" menu for MSC in LIB directories it appears the directory "C:\Program Files\Microsoft SDKs\Windows\v6.1\lib". Gdi32.lib is located there for MSC. Best regards Koldo
SDK libs is in "C:\Program Files\Microsoft Visual Studio 9.0\Vc\Lib" Is configured in "Build methods"! file Gdi32.lib I founded by address: C:\Program Files\Microsoft Visual Studio 9.0\Vc\Lib!
Hello tojocky Excuse me . Your answer is clear, but in my theide I have this: After Visual C++ Express and SDK installation, gdi32.lib file is installed under "Microsoft SDKs". Please confirm me that gdi32.lib file is located under C:\Program Files\Microsoft Visual Studio 9.0\Vc\Lib instead of under C:\Program Files\Microsoft SDKs\Windows\v6.1\lib Best regards Koldo
Hello Koldo, I have the same situation with this difference: "C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib" instead "C:\Program Files\Microsoft SDKs\Windows\v6.1\lib" The gdi32.lib library is located in folder: "C:\Program Files\Microsoft SDKs\Windows\v6.1\lib" I want to notice that when i tried to build this demo under MSC8 with the latest source svn code I have following errors: ----- SysInfo ( MT MSC8 FORCE_SIZE WIN32 MSC ) (3 / 5) SysInfo.cpp D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1179) : error C2065: 'PRODUCT_ULTIMATE' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1179) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1182) : error C2065: 'PRODUCT_HOME_PREMIUM' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1182) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1185) : error C2065: 'PRODUCT_HOME_BASIC' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1185) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1188) : error C2065: 'PRODUCT_ENTERPRISE' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1188) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1191) : error C2065: 'PRODUCT_BUSINESS' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1191) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1194) : error C2065: 'PRODUCT_STARTER' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1194) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1197) : error C2065: 'PRODUCT_CLUSTER_SERVER' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1197) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1200) : error C2065: 'PRODUCT_DATACENTER_SERVER' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1200) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1203) : error C2065: 'PRODUCT_DATACENTER_SERVER_CORE' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1203) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1206) : error C2065: 'PRODUCT_ENTERPRISE_SERVER' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1206) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1209) : error C2065: 'PRODUCT_ENTERPRISE_SERVER_CORE' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1209) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1212) : error C2065: 'PRODUCT_ENTERPRISE_SERVER_IA64' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1212) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1215) : error C2065: 'PRODUCT_SMALLBUSINESS_SERVER' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1215) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1218) : error C2065: 'PRODUCT_SMALLBUSINESS_SERVER_PREMIUM' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1218) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1221) : error C2065: 'PRODUCT_STANDARD_SERVER' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1221) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1224) : error C2065: 'PRODUCT_STANDARD_SERVER_CORE' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1224) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1227) : error C2065: 'PRODUCT_WEB_SERVER' : undeclared identifier D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1227) : error C2051: case expression not constant D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1230) : warning C4060: switch statement contains no 'case' or 'default' labels D:\source_codes\upp\svn_google\bazaar\SysInfo\SysInfo.cpp(1233) : error C2065: 'SM_SERVERR2' : undeclared identifier SysInfo: 1 file(s) built in (0:01.29), 1297 msecs / file, duration = 1312 msecs, parallelization 0% There were errors. (0:01.39) Thank you for you contribution! After build this with MINGW I can propouse to divide OfficeSheet into OfficeBook and OfficeSheet. It can be add possibility to add more sheets under one book (file)!
Hello tojocky - About the gdi32.lib problem The issue is to link the program with gdi32.lib I have tested it now with v6.1 and v6.0A and both link and run well . Please check it and tell me what happens. - About MSC8 "undeclared identifier" errors Reading sysinfo.cpp from line around 1100 you will see: #if defined(__MINGW32__) //#define PRODUCT_UNDEFINED 0x00000000 #define PRODUCT_ULTIMATE 0x00000001 #define PRODUCT_HOME_BASIC 0x00000002 #define PRODUCT_HOME_PREMIUM 0x00000003 ... They serve to define Win OS version. As I have only tested this with MinGW and MSC9 I saw that these includes where in ...\Microsoft SDKs\Windows\v6.1\Include\WinNT.h, so they were included for MinGW as MSC9 did not need them. The SM_SERVERR2 #include is in ...\Microsoft SDKs\Windows\v6.1\Include\WinUser.h and in ...\mingw\include\winuser.h, so I did not include it. For using them in MSC8 they would have to be included. - About Sheets and Books Ok. Let me some days and I will do it. Thank you for testing and giving feedback Best regards Koldo
Hello Koldo! When I put gdi32 in "package organizer" for SysInfo with MSC9 was compile and run OK! Please change this in svn (bazaar) too! With MSC8 I modified your code and works too: i modified: #if !defined(PRODUCT_ULTIMATE) #define PRODUCT_ULTIMATE 0x00000001 #define PRODUCT_HOME_BASIC 0x00000002 #define PRODUCT_HOME_PREMIUM 0x00000003 #define PRODUCT_ENTERPRISE 0x00000004 #define PRODUCT_HOME_BASIC_N 0x00000005 #define PRODUCT_BUSINESS 0x00000006 #define PRODUCT_STANDARD_SERVER 0x00000007 #define PRODUCT_DATACENTER_SERVER 0x00000008 #define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 #define PRODUCT_ENTERPRISE_SERVER 0x0000000A #define PRODUCT_STARTER 0x0000000B #define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C #define PRODUCT_STANDARD_SERVER_CORE 0x0000000D #define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E #define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F #define PRODUCT_BUSINESS_N 0x00000010 #define PRODUCT_WEB_SERVER 0x00000011 #define PRODUCT_CLUSTER_SERVER 0x00000012 #define PRODUCT_HOME_SERVER 0x00000013 #define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 #define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 #define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 #define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 #define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019 #define PRODUCT_UNLICENSED 0xABCDABCD #define SM_SERVERR2 89 #endif instead: #if defined(__MINGW32__) //#define PRODUCT_UNDEFINED 0x00000000 #define PRODUCT_ULTIMATE 0x00000001 #define PRODUCT_HOME_BASIC 0x00000002 #define PRODUCT_HOME_PREMIUM 0x00000003 #define PRODUCT_ENTERPRISE 0x00000004 #define PRODUCT_HOME_BASIC_N 0x00000005 #define PRODUCT_BUSINESS 0x00000006 #define PRODUCT_STANDARD_SERVER 0x00000007 #define PRODUCT_DATACENTER_SERVER 0x00000008 #define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 #define PRODUCT_ENTERPRISE_SERVER 0x0000000A #define PRODUCT_STARTER 0x0000000B #define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C #define PRODUCT_STANDARD_SERVER_CORE 0x0000000D #define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E #define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F #define PRODUCT_BUSINESS_N 0x00000010 #define PRODUCT_WEB_SERVER 0x00000011 #define PRODUCT_CLUSTER_SERVER 0x00000012 #define PRODUCT_HOME_SERVER 0x00000013 #define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 #define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 #define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 #define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 #define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 #define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019 #define PRODUCT_UNLICENSED 0xABCDABCD #endif be care... I added new define: #define SM_SERVERR2 89 Maybe i did something wrong, but it was compiled and runed ok with all 3 compilers: MSC8, MSC9 and MINGW.
Hello tojocky - About gdi32.lib I suppose that the reason of this is that I added this lib in the last sysinfo version. I probably updated in Bazaar the sources but not the upp file. - About MSC8 Added the includes Best regards Koldo
Hello Koldo! I added new methods for classes OfficeSheet and MSSheet: // >>>Ion Lupascu 06.05.2009 Add this methods int GetSheetsCount(); bool SetActiveSheet(int index); bool SetActiveSheet(String name); bool SetSheetName(String new_name); // <<<Ion Lupascu 06.05.2009 Details for MSSheet: // >>> Ion Lupascu 06.05.2009 Add this methods int MSSheet::GetSheetsCount(){ if (!Book) return(-1); return((int)Ole::GetValue(Ole::GetObject(Book, "Sheets"), "Count")); } // Set active sheet start with 0(zero) bool MSSheet::SetActiveSheet(int index){ if(!Book) return false; VariantOle index_ole; index_ole.Int4(index + 1); if (!(Sheet = Ole::GetObject(Book, "Sheets", index_ole))) return false; return true; } // Set active sheet by name bool MSSheet::SetActiveSheet(String name){ if(!Book) return false; VariantOle name_ole; name_ole.BString(name); if (!(Sheet = Ole::GetObject(Book, "Sheets", name_ole))) return false; return true; } bool MSSheet::SetSheetName(String new_name){ if(!Sheet) return false; VariantOle new_name_ole; new_name_ole.BString(new_name); return Ole::SetValue(Sheet, "Name", new_name_ole); } // <<< Ion Lupascu 06.05.2009 Details for OfficeSheet: // >>> Ion Lupascu 06.05.2009 Add this methods int OfficeSheet::GetSheetsCount(){ if (!data) return -1; if (type == SheetOPEN) return -1; //... need to add ((OPENSheet*)data)->GetSheetsCount(); else if (type == SheetMS) return ((MSSheet*)data)->GetSheetsCount(); else return -1; } // Set active sheet start with 0(zero) bool OfficeSheet::SetActiveSheet(int index){ if (!data) return false; if (type == SheetOPEN) return false; //... need to add ((OPENSheet*)data)->SetActiveSheet(index); else if (type == SheetMS) return ((MSSheet*)data)->SetActiveSheet(index); else return false; } // Set active sheet by name bool OfficeSheet::SetActiveSheet(String name){ if (!data) return false; if (type == SheetOPEN) return false; //... need to add ((OPENSheet*)data)->SetActiveSheet(name); else if (type == SheetMS) return ((MSSheet*)data)->SetActiveSheet(name); else return false; } bool OfficeSheet::SetSheetName(String new_name){ if (!data) return false; if (type == SheetOPEN) return false; //... need to add ((OPENSheet*)data)->SetActiveSheet(name); else if (type == SheetMS) return ((MSSheet*)data)->SetSheetName(new_name); else return false; } // <<< Ion Lupascu 06.05.2009 I do not added this method for Open office. Please check this and add methods for Open calc too. Maybe exists memory leak in method: // Set active sheet by name bool MSSheet::SetActiveSheet(String name){ if(!Book) return false; VariantOle name_ole; name_ole.BString(name); >>HERE if (!(Sheet = Ole::GetObject(Book, "Sheets", name_ole))) return false; return true; } I tested this new methods and works fine! Thank you for changes with MSC8 and gdi32.lib
Hello Tojocky Thank you for your effort. Please next time tell me that you are going to implement code to avoid doing the things twice . I had done almost all this morning!!! About function naming, if you see class OPENSheet you will see: class OPENSheet { ... // New functs for next versions bool InsertTab(String name); bool ChooseTab(String name); bool ChooseTab(int index); int GetNumTabs(); These functions are already implemented in Automation.cpp for OpenOffice!! As I did not implement them in MSOffice I did not make them visible before. The final thing I am doing now and sometimes is the most difficult is to have just the same behaviour with OpenOffice and MSOffice implementations, as in some things they do not work the same. Please, believe me. You have done the things well. Please next time tell me you are going to do the job before. Best regards Koldo
Hello Koldo! No problems! I created this temporarily, because I needed this today. You can change as you want, no problems, I only went to suggest this realization! Will be great set cell/range format: in MSExcel can be: Cells(row, col).NumberFormat = "@" The problems is when i try to write a number as text!
tojocky wrote on Wed, 06 May 2009 12:25 Hello Koldo! No problems! I created this temporarily, because I needed this today. You can change as you want, no problems, I only went to suggest this realization! Will be great set cell/range format: in MSExcel can be: Cells(row, col).NumberFormat = "@" The problems is when i try to write a number as text! Hello tojocky Now there is not included a way to set the format, but when you write text, number or dates they has to appear right. In the demo you see: sheet.SetValue(2, 2, "=A7*B5"); sheet.SetValue(3, 21, "Hello"); sheet.SetValue("BD25", 23242.343); sheet.SetValue("B26", GetSysTime()); The output of this should be as expected. Could you explain me what you need with more detail?. Best regards Koldo
Hello Koldo, Try this for Ms Excel in demo example: sheet.SetValue(1, 2, "123456789123456789"); I have lost data: for this example in excel I have "123456789123456000" instead "123456789123456789" I was modified a little the code: bool MSSheet::SetValue(int col, int row, Value value) { if (!Sheet) return false; VariantOle x, y, val; x.Int4(col); y.Int4(row); val.Value(value); // >>> Ion Lupascu 06.05.2009 Set Cell Format for string cell if (!(Range = Ole::GetObject(Sheet, "Cells", x, y))) return false; if(IsString(value)){ VariantOle txt_format_ole; txt_format_ole.BString("@"); Ole::SetValue(Range, "NumberFormat", txt_format_ole); } return Ole::SetValue(Range, "Value", val); // <<< Ion Lupascu 06.05.2009 } I thing that exist memory leak in the program! Every time when I run the program that it only preparing excel file and text file (specific converting from text to excel file) I have memory leak. Memory usage is increasing every time! Is it a normal situation?
Hello tojocky I have updated in Bazaar Automation and Sysinfo. The functions added are: class OfficeSheet { public: ... bool InsertTab(String name); bool ChooseTab(String name); bool ChooseTab(int index); bool RemoveTab(String name); bool RemoveTab(int index); int GetNumTabs(); ... They support both OpenOffice Calc and Excel and have the same behaviour. I have included in demo sheet.SetValue(1, 2, "'123456789123456789"); This is a special case because this number is over the Calc and Excel precision, so if you want to get all the digits you have to enter it as text. For me the easiest way is just adding a ' in the beginning. I have not found any memory leak. Try to use the new code from svn and tell me the details if you get something wrong. Thank you for your efforts Koldo
Hello Koldo! I tested from svn and do not found your changes about adding in package organizer "gdi32" for package SysInfo and in demo package the code: sheet.SetValue(1, 2, "'123456789123456789"); Maybe I do not check correct svn repository? I use: http://upp-mirror.googlecode.com/svn/trunk/ Edit: I want to add that to add a symbol as ' is not a solution! May be will be great to add method SetFormatSelection that as parameter will be an enum with restricted values as (String)? It will be nice because the format realization for MS Excel can differ by Open Office Calc!
Hello tojocky I have had difficulties with svn. Finally it is updated in bazaar. - About the ' symbol I really use it in the every day spreadsheet use. For me it is faster to do it than choosing the cell, open the format menu looking for the text format and after that, enter the string. It is simple and it works. Neither Calc/Excel nor OfficeSheet knows better than the user the real format of strings that are not clear, like: - 123456789123456789 or - 00123 I do not know to include your code... that is really Ok Quote: if(IsString(value)){ VariantOle txt_format_ole; txt_format_ole.BString("@"); Ole::SetValue(Range, "NumberFormat", txt_format_ole); } as for "123456789123456789" and "123", they will be considered as text and it will not be possible to do any mathematical operation with them. This can be a source of problems. - About SetFormatSelection Well, something has to be done. I considered that to have less priority as: -- I have to prepare the same interface for Calc and Excel -- I found more interesting and easier to do cells formating with colors, more font handling and borders They are opinions. Please tell me what are the most important format options to be included. If you plan to do something please tell me in advance so that we will not repeat the job. Best regards Koldo
Hello Koldo! My Opinion about adding the method "SetSelectionFormat" is important, for me. This method can resolve my problems. I suggest to add this method: bool MSSheet::SetValue(Value value) { if (!Sheet) return false; if (!Range) return false; VariantOle val; val.Value(value); return Ole::SetValue(Range, "Value", val); } I realized only for MSExcel variant! Other methods to do is important too! Thank you for realization!
Hello Koldo! Seems I found a little interesting project that read and write excel in direct stream file for Excel 97-2003. http://www.codeproject.com/KB/office/BasicExcel.aspx And other example I found in c# for excel 2007 write and read. http://www.codeproject.com/KB/office/OpenXML.aspx In Excel 2007 the format is more readable.
Thank you tojocky I agree they are good samples of accesing directly Microsoft formats. Other good effort is Jakarta POI. The problem of it is that it is addressed to Java. When thinking in Automation package I was tempted to access directly the files. The advantage was clear: you do not need the Office software to do it and you do not depend on the OS (how to access Microsoft files from GNU/Linux?). The problem I had was that .xls, .doc, .ods, .otd are from complex to very complex formats and I did not found libraries that covered their main features. Finally I chose to go through Ole automation and UNO api. For me they have not been easy to use. Bad documented from a C point of view after many efforts I had to refuse to use UNO to handle OpenOffice and so to handle it from Linux as there is no Ole clone. Well, that is my experience. More ideas are acknowledged. Best regards Koldo
People, could you please rename Automation package into, i.e. Docflow, Microsoft, or Office. "Automation" stands for many things, especially industrial automation. So "automation" IMO is much less informative and more confusing than "Docflow".
koldo wrote on Wed, 13 May 2009 15:09 Thank you tojocky I agree they are good samples of accesing directly Microsoft formats. Other good effort is Jakarta POI. The problem of it is that it is addressed to Java. When thinking in Automation package I was tempted to access directly the files. The advantage was clear: you do not need the Office software to do it and you do not depend on the OS (how to access Microsoft files from GNU/Linux?). The problem I had was that .xls, .doc, .ods, .otd are from complex to very complex formats and I did not found libraries that covered their main features. Finally I chose to go through Ole automation and UNO api. For me they have not been easy to use. Bad documented from a C point of view after many efforts I had to refuse to use UNO to handle OpenOffice and so to handle it from Linux as there is no Ole clone. Well, that is my experience. More ideas are acknowledged. Best regards Koldo I founded and MSWord too! But the MSOffice 2007 is based on XML file compressed with gzip. May we try to concentrate our power to manipulate direct with file (.xls, xlsx, .doc, .docx)? Other formats I do not use!
Hello tojocky .doc and .xls are not documented binary formats only recognized by hacking. The only way for an average human (like me) to access them is by using a library. Open Document and Open XML are well documented open formats. The problem is the size of these standards: - Open Document. Standard ISO/IEC 26300. 722 pag - Open XML. Standard ISO/IEC 29500. 7228 pages The huge size of 722 pages seems small comparing to the 7228 pages of the microsoft standard. I can not answer properly as I do not know them, but it seems a hard work to try to use only a small percentage of them. I repeat, I am an average person. Best regards Koldo
Many parts of Open XML definition are optional, i.e. you don't need to support them. edit: some of those optional are defined in a funny way like "following behavior of some legacy SW" without further details, so even if you try to support it, you will fail. Then again it's just question of time when Microsoft Office will produce files (even simple ones) with so many optional tags as possible to prevent anybody else working with that format, so I would not bother too much with that ISO standard. The ODF is other kind of beast, you can 100% support the ISO standard, yet for example it doesn't say nothing particular about formulas in spreadsheets, so you are still not supporting real world ODF files very good. If you want to support real world files, you must also follow current Open Office way of doing things. This situation has at least the advantage that the OOo legacy is de facto standard which will work, the only ODF vendor breaking this is Microsoft (are you surprised? ) with latest MS Office service pack they do support the ISO part of ODF and everything else what will become part of version2 of ODF definition they do in different way, so their support of ODF "is there", but practically unusable.
Well, I guess nobody liked the idea of renaming Automation to OleAutomation.
Mindtraveller wrote on Fri, 15 May 2009 14:15 Well, I guess nobody liked the idea of renaming Automation to OleAutomation. I certainly do, but I'm merely passing by, it's up to others.
mr_ped wrote on Fri, 15 May 2009 14:26 Mindtraveller wrote on Fri, 15 May 2009 14:15 Well, I guess nobody liked the idea of renaming Automation to OleAutomation. I certainly do, but I'm merely passing by, it's up to others. Well, I put Automation name because: - I wanted to use it also in Linux for OpenOffice through its UNO interface - Really "Ole Automation" is the old name as Microsoft renamed the technology to simply "Automation" I have the hope that in the next future it would be possible to interface OpenOffice in Linux so I would not add "Ole" to the package name. Best regards Koldo
I`m afraid the word "Automation" has many meanings beyond plain docflow. Therefore it will be confusing for people who is not closely connected to office applications only (my first reaction was "Wow, industrial automation package for U++! Let`s look what microcontrollers are supported..."). My proposal is avoid confusion from the start and select more appropriate naming for what is really your package is doing, such as: Office (IMO the best choice), Docflow, OleAutomation, etc.
Hello mr_ped I like it. If everybody agrees this week I would change the name next Monday. Best regards Koldo
Change done. Now Automation package is called OfficeAutomation. I have also included ES/ES translation and I have began with the documentation. Best regards Koldo
Hello Koldo! I found here interesting library for direct manage .xls file. What is your opinion? Ion Lupascu (tojocky)
Answered here: http://www.ultimatepp.org/forum/index.php?t=msg&goto=218 94&#msg_21894
In 5485 U++ on 64bit Win7 and Office 2003 after this simple code WINWORD is staying in process list: OfficeDoc word; if (word.IsAvailable("Open")) word.Init("Open"); else if (word.IsAvailable("Microsoft")) word.Init("Microsoft"); word.Quit();
Hello iST1 You are right . Problem found and solved. Please update your source tomorrow.
Fine, from here http://www.ultimatepp.org/www$uppweb$nightly$en-us.html? Is there a list of changes in nightly builds?
Hello iST1, The list of changes in upp you can find on following website: code.google.com/p/upp-mirror/source/list. Sincerely, Klugier
I struggle with the problem of embedding Word. This is howto (::SetParent way is the same as in correctly worked http://www.codeproject.com/Articles/3582/Word-Control-for-NE T): class MainFrm : public TopWindow { public: OfficeSheet sheet; OfficeDoc doc; MainFrm() {} void TestExcel() { if (sheet.IsAvailable("Open")) { sheet.Init("Open"); } else if (sheet.IsAvailable("Microsoft")) { sheet.Init("Microsoft"); } sheet.AddSheet(true); EmbedAsFrame("XLMAIN"); } void TestWord() { if (doc.IsAvailable("Open")) { doc.Init("Open"); } else if (doc.IsAvailable("Microsoft")) { doc.Init("Microsoft"); } doc.AddDoc(true); EmbedAsFrame("Opusapp"); } void EmbedAsFrame(const String &className) { HWND embeded = FindWindow(className, NULL); ::SetParent(embeded, GetHWND()); Rect r = GetScreenView(); Rect pr = GetScreenClient(GetHWND()); MoveWindow(embeded, r.left - pr.left, r.top - pr.top, r.Width(), r.Height(), 0); } }; GUI_APP_MAIN { MainFrm w; w.Open(); //w.TestExcel();//embeded #if 1 w.TestWord();//opened in separated window #else //if we manualy opened some Word, it embeded w.EmbedAsFrame("Opusapp"); #endif w.Run();
It is a dirty trick A version just for Word and included Layout(). There are details to be improved but this could be a base. #include <OfficeAutomation/OfficeAutomation.h> using namespace Upp; class WordFrm : public TopWindow { public: WordFrm() { Sizeable().Zoomable(); embedded = 0; } void Embed() { if (doc.IsAvailable("Microsoft")) doc.Init("Microsoft"); doc.AddDoc(true); String className = "Opusapp"; embedded = FindWindow(className, NULL); ::SetParent(embedded, GetHWND()); Layout(); } private: OfficeDoc doc; HWND embedded; virtual void Layout() { if (embedded == 0) return; Rect r = GetScreenView(); Rect pr = GetScreenClient(GetHWND()); MoveWindow(embedded, r.left - pr.left, r.top - pr.top, r.Width(), r.Height(), 0); } }; GUI_APP_MAIN { WordFrm w; w.Open(); w.Embed(); w.Run(); }
I have no another way to do what customer wants:p For You the code above is working with Word? What my Word (separately): What my Excel (embedded): I need Word embedded...
Hello iST1 The code included works basically well for me with W7-64 Office 2010. The embedded Word moves and resizes with U++ window. However there is some flickering in the Word window frame. The next step could be to remove Word window frame to avoid this.
I do not have Office > 2003, but can you give me some advice about frame removing? Something like this int counter = ActiveWindow.Application.CommandBars.Count; for(int i = 0; i < counter;i++) ActiveWindow.Application.CommandBars[i].Enabled=false; } Also can be Close method added to Automation?
iST1 wrote on Mon, 23 September 2013 15:29 I do not have Office > 2003, but can you give me some advice about frame removing? Something like this int counter = ActiveWindow.Application.CommandBars.Count; for(int i = 0; i < counter;i++) ActiveWindow.Application.CommandBars[i].Enabled=false; } Also can be Close method added to Automation? Hello iST1 I do not know what do you mean with "frame removing". What would have to do Close()? This code is better but flickering remains: #include <OfficeAutomation/OfficeAutomation.h> using namespace Upp; class WordFrm : public TopWindow { public: WordFrm() { Sizeable().Zoomable(); embedded = 0; } void Embed() { if (doc.IsAvailable("Microsoft")) doc.Init("Microsoft"); doc.AddDoc(true); embedded = FindWindow("Opusapp", NULL); LONG lStyle = GetWindowLong(embedded, GWL_STYLE); lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU | WS_BORDER | WS_DLGFRAME | WS_SIZEBOX); SetWindowLong(embedded, GWL_STYLE, lStyle); LONG lExStyle = GetWindowLong(embedded, GWL_EXSTYLE); lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE); SetWindowLong(embedded, GWL_EXSTYLE, lExStyle); SetWindowPos(embedded, NULL, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER); ::SetParent(embedded, GetHWND()); Layout(); } private: OfficeDoc doc; HWND embedded; virtual void Layout() { if (embedded == 0) return; Rect r = GetScreenView(); Rect pr = GetScreenClient(embedded); MoveWindow(embedded, r.left - pr.left, r.top - pr.top, r.Width(), r.Height(), TRUE); } virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_SIZE) Layout(); return TopWindow::WindowProc(message, wParam, lParam); } }; GUI_APP_MAIN { WordFrm w; w.Open(); w.Embed(); w.Run(); }
I mean removing all Word/Excel command bars - only document view like in preview mode. Close method need fot close document before open.
Hello iST1 Please post the VBA code to do it and probably it will be rather easy to implement it. There are many forum explaining the details.
Private Sub Workbook_Open() For Each cmd In ActiveWindow.Application.CommandBars cmd.Enabled = False Next End Sub Thanks in advance
Hello iST1 I have tried it but it does not work in Office 2007 and higher. It is due to the new Office menus (called "Fluent") work in a completely different way.
This is strange, because .net code here work perfectly with Word 2007 and use the analogue of the VBA above code + SetParent method.
Installed: MS Office 2007 and Open Office 4. In #if 1 code opened MS Doc + MS Excel In #if 0 code (in sub thread) opened MS Doc + Open Calc Why MS Excel inavaylable in thread and how to set the priority for Microsoft? Thread used to preinit costly loading. class OfficeTest : public TopWindow { public: typedef OfficeTest CLASSNAME; OfficeTest() { #if 1 Check(); #else Thread().Start(THISBACK(Check)); #endif } void Check() { if (sheet.IsAvailable("Microsoft")) { sheet.Init("Microsoft"); sheet.AddSheet(true); } else if (sheet.IsAvailable("Open")) { sheet.Init("Open"); sheet.AddSheet(true); } if (doc.IsAvailable("Microsoft")) { doc.Init("Microsoft"); doc.AddDoc(true); } else if (doc.IsAvailable("Open")) { doc.Init("Open"); doc.AddDoc(true); } } private: OfficeSheet sheet; OfficeDoc doc; }; GUI_APP_MAIN { OfficeTest().Run(); }
What is more, if we exchange the order of testing Excel if (sheet.IsAvailable("Open")) { sheet.Init("Open"); sheet.AddSheet(true); } else if (sheet.IsAvailable("Microsoft")) { sheet.Init("Microsoft"); sheet.AddSheet(true); } opened MS Excel instead Open Calc
iST1 wrote on Thu, 26 September 2013 17:47 This is strange, because .net code here work perfectly with Word 2007 and use the analogue of the VBA above code + SetParent method. Hello iST1 I have tried that code and it works well, although as I previously reported it does not remove the menus. You can see the explanation here ( http://social.msdn.microsoft.com/Forums/office/en-US/c329f3e 5-0e25-44a2-8b07-1182d428de37/how-to-disable-menu-bar-in-wor d-2007-programmatically-in-c). In summary: Word 2007 (and later versions) no longer use the CommandBars (Menu and toolbars) for the UI. This was changed, for various reasons, not least of which to explicitly prevent applications running out-of-process from interfering in the application's UI. Among other considerations, this is a security measure to prevent outside apps from leveraging the Office object models for "bad intentions". So the short answer to your request is that there is no way for your app to affect an Office UI that implements the Ribbon (Office Fluent UI). The Ribbon can be defined only by RibbonXML embedded in an Office document, or that is part of a COM Add-in (implements the IDT2Exensibility interface). Possibly, you could create a custom template that contains a RibbonXML with startFromScratch attribute set to True. That will reduce available Ribbon commands to a minimum. It's not possible, however, to remove all commands from the UI. Certain ones in Office 2007 are always enabled, in order to allow the user to have final control over the Office environment.
iST1 wrote on Fri, 27 September 2013 11:32 What is more, if we exchange the order of testing Excel if (sheet.IsAvailable("Open")) { sheet.Init("Open"); sheet.AddSheet(true); } else if (sheet.IsAvailable("Microsoft")) { sheet.Init("Microsoft"); sheet.AddSheet(true); } opened MS Excel instead Open Calc Hello iST1 OfficeAutomation is not designed to be multithreaded. If you really need that feature I will try to implement it.
Since application works with collection of Word/Excel and IsAvailable method a costly by time, i don't call him in main GUI thread. I decided to open every files in single form (FilePreviewCmd in code). For this i calling: Single<FilePreviewCmd>().StartInit(); If there is an alternative way, I'll take it. void FilePreviewCmd::StartInit() { //CheckOfficePlugins(false);//sync thread_.Run(THISBACK1(CheckOfficePlugins, true));//acync } void FilePreviewCmd::CheckOfficePlugins(bool preinit) { isXlsOpen = sheet.IsAvailable("Open"); isXlsMS = sheet.IsAvailable("Microsoft"); if (!isXlsMS) isXlsOpen = sheet.IsAvailable("Open"); isDocMS = doc.IsAvailable("Microsoft"); if (!isDocMS) isDocOpen = doc.IsAvailable("Open"); if (preinit) PostCallback(THISBACK(InitOfficePlugins)); else InitOfficePlugins(); } void FilePreviewCmd::InitOfficePlugins() { if (isXlsMS) { sheet.Init("Microsoft"); } else if (isXlsOpen) { sheet.Init("Open"); } if (isDocMS) { doc.Init("Microsoft"); } else if (isDocOpen) { doc.Init("Open"); } TopWindow::Open(); }
Hello iST1 It seems that main thread calls a thread with CheckOfficePlugins() that calls another thread with InitOfficePlugins() that opens main window. Am I right?
Yes, except that FilePreviewCmd::InitOfficePlugins opens FilePreviewCmd child window. StartInit called from main window. InitOfficePlugins introduced as a main thread procedure, then otherwise crushes occur and i don't know why.
Hello iST1 InitOfficePlugins() seems to be open in a thread so calling TopWindow::Open() will be dangerous. I imagine that you would like to launch from the main thread a thread doing the inits and after that to run from the main thread the automation, without any additional thread. Is not it?
Oh, i have not noticed what InitOfficePlugins with Open can be used after thread_.Wait() in the main thread, but thread_.Run(THISBACK1(CheckOfficePlugins, true)) is needed for speedup.
Hello, sorry to hijack the thread, I just want to ask something that I think is most relevant here than anywhere else. Does anybody know how to create an ActiveX control with U++ so that it can be embedded, for instance, in a Word document? For instance, how to modify the Scatter control so that one can display, and possibly scroll around, graphs inside Word or PowerPoint or any other COM server. Thanks, Kel