I'm using VS2010 C++ and Office 2010 to create reports based on Excel templates. C++ can successfully open, insert values & save the xlsx as something else but I'd like it to also save it as PDF. I'm struggling with the _variant_t parameters of the ExportAsFixedFormat() function despite seeing examples in VB, C# and PowerShell. Can anybody provide example code?
The shell of my functionality:
Excel::_ApplicationPtr pXL;
if (FAILED(pXL.CreateInstance("Excel.Application")))
{
return FALSE;
}
pXL->Workbooks->Open("c:\\tempRep.xlsx");
pXL->PutVisible(0, FALSE);
// Get the active worksheet
Excel::_WorksheetPtr pWksheet = pXL->ActiveSheet;
//... use the spreadsheet
// Save the worksheet
pWksheet->SaveAs("c:\\newRep.xlsx");
pWksheet->ExportAsFixedFormat(??const _variant_t &Filename, ....??)
Thanks, Steve
Try using the SetString method:
_variant_t Filename;
Filename.SetString("c:\\temp\\myfile.txt");
pWksheet->ExportAsFixedFormat(Filename, ....)
From Microsoft 's document, it is 0 or 1 and works for me.
https://msdn.microsoft.com/en-us/library/bb241296(v=office.12).aspx
VARIANT vtMissing; // VARIANT defining a missing/optional parameter.
vtMissing.vt = VT_ERROR;
vtMissing.scode = DISP_E_PARAMNOTFOUND;
book.ExportAsFixedFormat(0, COleVariant(TEXT("myExportPDF.pdf")), vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing);
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 have 2 variables, and I want to insert their values into a MySQL database, but I don't know how to do this.
Here is the all of my code so far, please correct/advise:
void RegistrationForm::Register()
{
istifadeciAdi.GetWindowText(i_ad);
par.GetWindowText(i_par);
parTekrar.GetWindowText(i_par_tekrar);
if (istifadeciAdi.GetWindowTextLength() != 0) // if you can please write this line better.
{
if (i_parol == i_parol_tekrar)
{
MySQL_Driver *driver;
Connection *dbConn;
Statement *statement;
//ResultSet *result; // I don't need this line any more
//PreparedStatement *ps;
driver = get_mysql_driver_instance();
dbConn = driver->connect("host", "u", "c");
dbConn->setSchema("mfc_app_database");
statement = dbConn->createStatement();
statement->executeQuery("INSERT INTO users(`username`, `password`) VALUES (/* how to use i_ad and i_par as variable to set column value? */)"); // executes the user "input"
/*ps = dbConn->prepareStatement("INSERT INTO users(`username`, `password`, `name`) VALUES (?)");
ps->setString(1, "cccc");
ps->setString(2, "ffff);*/
//delete result;
//delete[] result;
/*delete ps;
delete[] ps;*/
delete statement;
delete[] statement; // don't use this line in your program as me
delete dbConn;
delete[] dbConn; // don't use this line in your program as me
}
else
MessageBox(L"Şifrə dəqiq təkrar olunmalıdır.", L"Xəbərdarlıq", MB_ICONWARNING);
}
else
AfxMessageBox(L"Boş qoymaq olmaz.");
}
Edit
There's no any error. But when I clicked the (Register) button it says:
Program stopped working
and after clicking the Debug button it takes me to line which insert query I wrote.
p.s Sorry for my poor English.
Use CString to make query.
For example:
CString strQuery;
strQuery.Format(_T("INSERT INTO users(`username`, `password`) VALUES ('%s', '%s')"),i_ad, i_par);
Before using this query string in executeQuery (or in other query commands) you must convert it to std::string. Because, execute, executeQuery and executeUpdate commands only accepts the std::string.So, add this lines:
CT2CA tempString(query);
std::string query(tempString);
And use this string in your execute command
statement->executeQuery(query);
The docs for that MySQL connector say to use statement::execute() for queries that don't return a resultset, and statement::executeQuery() when there is a single row resultset.
So for SQL INSERT INTO maybe your problem is that you should be using execute.
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.
I'm attempting to convert a soap query written for C# into a gSoap query in Visual C++.
The C# query adds an XML node's to the query call, in order to pass parameters to the query:
XmlNode queryOpts = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");
queryOpts.InnerXml = "<DateInUtc>TRUE</DateInUtc>";
Here's the C# query, passing various args (some args are specified as XmlNode objects)
XmlNode nodeListItems = listService.GetListItems("Announcements", null, query, viewFields, null, queryOpts, null);
The C++ / gSoap query allows me to pass a query and response object:
listService.__ns10__GetListItems(&announcementQuery, &announcementResponse)
The query object has various properties that can be set that relate to the arguments in the C# call:
announcementQuery.listName
announcementQuery.query
announcementQuery.queryOptions
announcementQuery.viewFields
The first argument there is a string, no problem.
The query, queryOptions and viewFields are a bit confusing.
"query" is a class of type _ns2__GetListItems_query, and it has the following functions & members:
soap_default()
soap_get()
soap_in()
soap_out()
soap_put()
soap_serialize()
soap_type()
__any
__mixed
for query, queryOptions and viewFields, I'd simply like to specify an xml formatted string, like the C# code does, but I'm not sure how this is done.
Can someone cast some experience on this?
thanks!
I'm assuming you've already discovered the answer to this, but I'll post some notes for posterity.
Here's a simple C++ demo for sending and XML doc to a ASP.NET web method.
int _tmain(int argc, _TCHAR* argv[])
{
Service1SoapProxy proxy;
_WebServiceNS1__HelloWorld helloWorld;
_WebServiceNS1__HelloWorld_xml xml;
_WebServiceNS1__HelloWorldResponse response;
xml.__any = "<doc><x>hi</x></doc>";
helloWorld.xml = &xml;
int result = proxy.HelloWorld(&helloWorld, &response);
fprintf(stdout, "result: %i\n", result);
switch(result)
{
case SOAP_OK:
fprintf(stdout, "Response: %s\n", response.HelloWorldResult);
break;
default:
break;
}
return 0;
}
Here's the trivial web method in the .NET service:
[WebMethod]
public string HelloWorld(XmlNode xml)
{
return string.Format("Your XML: {0}", xml.OuterXml);
}
If everything works, you'll see "Response: hi" on your console.
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