I want to dynamically create and populate an excel spreadsheet with C++ builder 2009, but I'm not entirely sure how to go about it. Searching the web, I've narrowed it down to using OLE Automation. Moreover, I'm looking for a document or programming tutorial that can get me started. Is there a simple programming tutorial that also thoroughly explains the concepts of OLE automation?
To open an excel spreadsheet:
Variant excelApp = Unassigned;
//EOleSysError is thrown if GetActiveObject does not succeed. i.e
//if Excel is not currently open.
try
{
excelApp = Variant::GetActiveObject("Excel.Application");
}
catch(EOleSysError& e)
{
excelApp = Variant::CreateObject("Excel.Application"); //open excel
}
excelApp.OlePropertySet("ScreenUpdating", true);
To get the current cell pointer:
Variant excelCell = excelSheet.OlePropertyGet("Cells");
To add values to excel:
// create a vararray of 5 elements starting at 0
int bounds[2] = {0, 4};
Variant variantValues = VarArrayCreate(bounds, 1, varVariant);
variantValues.PutElement(5, 0);
variantValues.PutElement(5, 1);
variantValues.PutElement(5, 2);
variantValues.PutElement(5, 3);
variantValues.PutElement(5, 4);
Variant cellRange = excelCell.OlePropertyGet(
"Range",
excelCell.OlePropertyGet("Item", rowindex, columnindex), // start cell
excelCell.OlePropertyGet("Item", rowindex2, columnindex2) // finishing cell
);
// place array into excel
cellRange.OlePropertySet(
"Value",
excelApp.OleFunction("Transpose", variantValues)
);
I hope this gets you started, you will probably need to include vcl.h and comobj.hpp.
Related
I try to get blob data from Oracle by OCI routines.
I use the next code but the exceute statement gives ther error: ORA-01008: not all variables bound
What do I wrong? Can anybody help me?
Thanks,
Kees Braaksma
void get_blob_data()
{
// The query
// The results of this methode
// if errstring is empty, the blob data can be found in the 4th parameter.
// otherwise the error is given in errstring
CString csQuery;
csQuery.Format("BEGIN get_blob('%s','%ld',:ERRSTRING,:BLOB); END;", "20", 200);
//init
OCIHandleAlloc((dvoid *)m_OCIEnvironment , (dvoid **)(&m_OCIStatement),
(ub4)OCI_HTYPE_STMT, (size_t)0, (dvoid **)0);
//Prepare statement voor query
OCIStmtPrepare(m_OCIStatement, m_OCIError, (text *)(csQuery),
(ub4)(strlen(csQuery)), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
// output variables
char *pszResult = (char*)malloc(256);
memset(pszResult, 0, sizeof(pszResult));
Blob *blob = new Blob();
m_pIndicator1 = malloc(sizeof(OCIInd));
m_pDefine1 = NULL;
OCIDefineByPos(m_OCIStatement, &m_pDefine1, m_OCIError, (ub4)1,
(dvoid*)*pszResult,
(sb4)256, SQLT_STR,
(dvoid*)m_pIndicator1,
(ub2*)0, (ub2*)0, (ub4)OCI_DEFAULT);
m_pIndicator2 = malloc(sizeof(OCIInd));
m_pDefine2 = NULL;
OCIDescriptorAlloc(m_OCIEnvironment, &blob, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0);
OCIDefineByPos(m_OCIStatement, &m_pDefine2,
m_OCIError, (ub4)2,
(dvoid*)blob,
(sb4)-1, SQLT_BLOB,
(dvoid*)m_pIndicator2,
(ub2*)0, (ub2*)0, (ub4)OCI_DEFAULT));
iStatus = OCIStmtExecute(m_OCISrvCtx, m_OCIStatement, m_OCIError, (ub4)1, (ub4)0,
(OCISnapshot *)NULL, (OCISnapshot *)NULL,
(ub4)OCI_DEFAULT);
// results:
// iStatus = -1;
// Errorstring: ORA-01008: not all variables bound
}
You don't have any OCIBindByName() calls. OCIDefineByPos() is used when running SQL queries, which you aren't.
It's odd that you use a mixture of %s and bind variables in the PL/SQL call. I think you want to use bind variables for all parameters.
One handy hint is to see how ODPI-C uses OCI. For LOBs you can get either locators or data directly. The latter is a lot faster, but limited to 1G. It's arguably easiest to install Python and cx_Oracle, and run some samples e.g. ReturnLobsAsStrings.py. You can trace the OCI calls in dpiOci.c.
There are some sample OCI programs (sadly not so accessible - your DBA may be able to install them), look out for cdemolb.c and cdemolbs.c
Best Oracle-users,
Still have problems with getting a blob from Oracle. I use it so less.
Most of the time I copy some code and a new query is working fine.
I asked my collegue to change the function.
New the query is:
select ngm_transactie_pck.get_checkout_blob('20','200') from dual
the result of this function is a blob.
So i programmed:
static OCILobLocator *blob = NULL;
after OCIHandleAlloc() and OCIStmtPrepare() as in previous example i have:
OCIDescriptorAlloc(m_OCIEnvironment, &blob, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0);
CIDefineByPos(m_OCIStatement, &m_pDefine2,
m_OCIError, (ub4)1,
(dvoid*)&blob,
(sb4)-1, OCI_DTYPE_LOB,
(dvoid*)m_pIndicator2,
(ub2*)0, (ub2*)0, (ub4)OCI_DEFAULT));
The call to OciDefineByPos() gives crash/stackoverflow.
What do I wrong?
Greetz,
Kees
I want to make a windows form app. You can write text in textBox'es and when you press a button, the app would create an excel file and write the text from the boxes. I got only the UI done, I know some basics but I have no idea how to combine MS Visual C++ and Excel.
There's a lot of libraries listed in this answer:
What is a simple and reliable C library for working with Excel files?
In addition "ExcelFormat Library" is basic, but it sounds like it will do everything you need. It's free and easy to use.
And Number Duck is a commercial library that I have created.
This is a C # code taken from https://code.google.com/p/excellibrary/,
Play a bit with this code in VC + + and make it work. :)
Syntax are different but if you think about it you'll see it's all the same. ;)
First you have to download ExcelLibrary.dll file and add it to the Reference Project.
Than add this two lines:
using namespace ExcelLibrary::CompoundDocumentFormat;
using namespace ExcelLibrary::SpreadSheet;
The aim of this project is provide a native .NET solution to create, read and modify
Excel files without using COM interop or OLEDB connection.
Currently .xls (BIFF8) format is implemented. In future .xlsx (Excel 2007) may also be
supported.
Example code:
//create new xls file
string file = "C:\\newdoc.xls";
Workbook workbook = new Workbook();
Worksheet worksheet = new Worksheet("First Sheet");
worksheet.Cells[0, 1] = new Cell((short)1);
worksheet.Cells[2, 0] = new Cell(9999999);
worksheet.Cells[3, 3] = new Cell((decimal)3.45);
worksheet.Cells[2, 2] = new Cell("Text string");
worksheet.Cells[2, 4] = new Cell("Second string");
worksheet.Cells[4, 0] = new Cell(32764.5, "#,##0.00");
worksheet.Cells[5, 1] = new Cell(DateTime.Now, #"YYYY\-MM\-DD");
worksheet.Cells.ColumnWidth[0, 1] = 3000;
workbook.Worksheets.Add(worksheet);
workbook.Save(file);
// open xls file
Workbook book = Workbook.Load(file);
Worksheet sheet = book.Worksheets[0];
// traverse cells
foreach (Pair<Pair<int, int>, Cell> cell in sheet.Cells)
{
dgvCells[cell.Left.Right, cell.Left.Left].Value = cell.Right.Value;
}
// traverse rows by Index
for (int rowIndex = sheet.Cells.FirstRowIndex;
rowIndex <= sheet.Cells.LastRowIndex; rowIndex++)
{
Row row = sheet.Cells.GetRow(rowIndex);
for (int colIndex = row.FirstColIndex;
colIndex <= row.LastColIndex; colIndex++)
{
Cell cell = row.GetCell(colIndex);
}
}
Ok I have written some basic generic webservices before but I have never tried to consume a 3rd party one.
The one I am trying to consume is
http://opendap.co-ops.nos.noaa.gov/axis/webservices/predictions/wsdl/Predictions.wsdl
I am not getting any results back from this what so ever and cannot figure out why.
More odd is it is not even reaching PredictionsClient_getPredictionsAndMetadataCompleted when I put a break point in the code it doesn't even reach it.
Any suggestions would be greatly appreciated
public void Bouy(double meters)
{
PredictionService.Parameters PredictionParams = new PredictionService.Parameters();
PredictionService.PredictionsPortTypeClient PredictionsClient = new PredictionService.PredictionsPortTypeClient();
GeoCoordinateWatcher gc = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
//gc.Position.Location.Latitude, gc.Position.Location.Longitude
GeoCoordinate myLocation = new GeoCoordinate(27.931631,-82.802582);
foreach (var bl in BouyLocation.GetAll())
{
GeoCoordinate otherLocation = new GeoCoordinate(bl.Lat, bl.Lon);
PredictionParams.beginDate = DateTime.Now.ToString("yyyyMMdd");
PredictionParams.endDate = DateTime.Now.AddDays(1.0).ToString("yyyyMMdd");
PredictionParams.stationId = bl.LocationID;
PredictionParams.timeZone = 0;
PredictionParams.unit = 1;
PredictionParams.dataInterval = 6;
PredictionsClient.getPredictionsAndMetadataCompleted += new EventHandler<PredictionService.getPredictionsAndMetadataCompletedEventArgs>(PredictionsClient_getPredictionsAndMetadataCompleted);
PredictionsClient.getPredictionsAndMetadataAsync(PredictionParams);
double mymeters = myLocation.GetDistanceTo(otherLocation);
if (mymeters < meters)
{
TextBlock DynTextBlock = new TextBlock
{
Name = "Appearance" + bl.LocationID,
Text = bl.LocationName + PredictionResult,
TextWrapping = System.Windows.TextWrapping.Wrap,
Margin = new Thickness(12, -6, 12, 0),
Style = (Style)Resources["PhoneTextSubtleStyle"]
};
DynamicAppearance.Children.Add(DynTextBlock);
this.nearByLocations.Add(new BouyLocationModel() { LocationName = bl.LocationName, LocationID = bl.LocationID, Lat = bl.Lat, Lon = bl.Lon });
}
}
var test = nearByLocations;
}
void PredictionsClient_getPredictionsAndMetadataCompleted(object sender, PredictionService.getPredictionsAndMetadataCompletedEventArgs e)
{
string err = e.Error.ToString();
PredictionResult = e.Result.ToString();
}
Loooking at the code you have here I think that you have used the importing of a ServiceReference to auto build the classes for you?
Unfortunately I have found that this is rather temperamental on WP7 and the only way I actually got it to work was when I connected it to a Microsoft WCF service. Connecting to anything else just doesn't work.
If you do google searches there are various pages talking about the fact it doesn't work and ways around it (which I couldn't get to work).
However, there are ways around it but it isn't as simple as the auto-generated stuff. Basically you do things manually.
Although there are other ways to manually create the web service what I did was follow the information in the following which worked well: http://zetitle.wordpress.com/2010/10/14/using-reactive-extensions-with-webrequest/
You will need to parse the response yourself but XML to LINQ works really well for this.
Hope that helps, or maybe someone will have the solution as it is something I am interested in knowing how to get working too
I am facing some prob in managed C++, I can fill my ListView , but I am unable to edit specific row at later time
I can fill like
listView1->View = View::Details;
listView1->Columns->Add("S.no",......
ListViewItem^ itmp = gcnew System::Windows::Forms::ListViewItem("100");
ListViewSubItem^ itms1 = gcnew ListViewSubItem(itmp, "12:12:12 PM");
itmp->SubItems->Add(itms1);
listView1->Items->Add(itmp);
I want to implement following VB code in managed C++ , but showing errors
Dim FindlvItem() As ListViewItem // here i am facing problem in conversion to c++ managed
FindlvItem = Me.ListView1.Items.Find("100", False)
FindlvItem(0).SubItems(0).Text = "01:01:01 AM"
I dont want to use foreach loop to save processing
vs.net 2008
You should be able to convert the code almost line for line to C++/CLI. The only problem is that Find will return a collection of list view items, not just a single item.
array<ListViewItem^>^ FindlvItem = ListView1->Items->Find("100",false);
if (FindlvItem->Length == 1)
{
FindlvItem[0]->SubItems[0]->Text = "01:01:01 AM";
} // if found
I'm trying to set the number format of a cell but the call to xlcFormatNumber fails leaving the cell number format as "General". I can successfully set the value of the cell using xlSet.
XLOPER xRet;
XLOPER xRef;
//try to set the format of cell A1
xRef.xltype = xltypeSRef;
xRef.val.sref.count = 1;
xRef.val.sref.ref.rwFirst = 0;
xRef.val.sref.ref.rwLast = 0;
xRef.val.sref.ref.colFirst = 0;
xRef.val.sref.ref.colLast = 0;
XLOPER xFormat;
xFormat.xltype = xltypeStr;
xFormat.val.str = "\4#.00"; //I've tried various formats
Excel4( xlcFormatNumber, &xRet, 2, (LPXLOPER)&xRef, (LPXLOPER)&xFormat);
I haven't managed to find any documentation regarding the usage of this command. Any help here would be greatly appreciated.
Thanks to Simon Murphy for the answer:-
Smurf on Spreadsheets
//It is necessary to select the cell to apply the formatting to
Excel4 (xlcSelect, 0, 1, &xRef);
//Then we apply the formatting
Excel4( xlcFormatNumber, 0, 1, &xFormat);