Crystal reports 11 RDC (COM API) displays printer dialog even when I tell it not to prompt - com

I'm using Crystal Reports 11's RDC (COM) API to print. My code looks like this:
HRESULT res = m_Report->SelectPrinter(b_driver, b_device, b_port);
if (FAILED(res)) return res;
// For these calls, the #import wrapper throws on error
m_Report->PutPrinterDuplex(dmDuplex);
m_Report->PutPaperSize(dmPaperSize);
m_Report->PutPaperSource((CRPaperSource)pdlg->GetDevMode()->dmDefaultSource);
if (m_Report->GetPaperOrientation() == crDefaultPaperOrientation)
m_Report->PutPaperOrientation(crPortrait);
VARIANT vfalse;
VariantInit(&vfalse);
vfalse.vt=VT_BOOL;
vfalse.boolVal=0;
res = m_Report->PrintOut(vfalse);
However, at the end of all this, crystal reports still shows its own printer selection dialog - but only for some reports, it seems. Why does crystal reports show a print dialog even when I pass false for promptUser? And how, then, can I suppress crystal reports' internal printer selection dialog and force it to use my values?
Edit: Whoops, CR11, not CR9.
Some further information:
The reports that work properly (ie, do not show the print dialog) are generated internally using the RDC API; we create a new report object, import subreports into it, then print the result. No problem there.
The reports that do not work properly (ie, force the print dialog to open) have been created with a previous version of crystal reports; however, opening and saving the report does not seem to help.
Sample reports in the Crystal Reports installation directory show the same problem.
I tried reproducing with VBScript; however, the result was that nothing was printed at all (no dialog, no nothing):
Set app = CreateObject("CrystalRuntime.Application.11")
Set report = app.OpenReport("C:\Program Files\Business Objects\Crystal Reports 11.5\Samples\en\Reports\General Business\Inventory Crosstab.rpt")
report.PrintOut(True)
rem Testing with a True parameter to force a print dialog - but no printout and nothing appears (no error either though)

First, let me preface that I'm not a C/C++ programmer, so I'm not able to test the code--my interaction w/ the SDK has been with the VB and .Net interface over the years.
I found the following code from BO's devlibrary:
// A dummy variant
VariantInit (&dummy);
dummy.vt = VT_EMPTY;
HRESULT hr = S_OK;
// Specify the path to the report you want to print
_bstr_t ReportPath("c:\\Program Files\\Business Objects\\Crystal Reports 11.5\\Samples\\En\\Reports\\General Business\\Inventory.rpt");
_variant_t vtEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);
// Instantiate the IApplication object
m_Application.CreateInstance("CrystalRuntime.Application.115");
//Open the Report using the OpenReport method
m_Report = m_Application->OpenReport(ReportPath, dummy)
//Print the Report to printer
m_Report->PrintOut(dummy, dummy, dummy, dummy);
Does it work? It should print the report with its 'default' printer settings and without prompting.
You wrote:
However, at the end of all this,
crystal reports still shows its own
printer selection dialog - but only
for some reports, it seems.
Generally speaking, I've found that Crystal tends to ignore commands to suppress dialogs if it thinks something is missing. I've found this to be true with the parameter dialog. Perhaps it apply to this situation as well. I would ask what is different about the reports that cause the dialog to be generated. There is a 'no printer' option that can be set. Perhaps this is the common thread.
Do you have access to the VB6 IDE? If you write the equivalent commands using VB6's interface, does the prompting occur?
You might also investigate using the CRPE32.dll instead of the report-designer control. To be honest, I don't know if the RDC wraps the CRPE DLL or is an entirely-separate code base.

Turns out it was a bug in my code after all - I'd previously put in a wrapper for the RDC API to fix certain other bugs we were having; due to the large number of methods in the IReport interfaces, I wrote a script to generate pass-through stubs for the methods I wasn't interested in. Turns out that script was passing in bogus values for parameters with default values. Oops! Fixing the wrapper code fixed the bug here.

Related

Runtime error "SYSTEM_ABAP_ACCESS_DENIED" when using SUBMIT via custom report

I am trying to use cl_salv_bs_runtime_info in order to get the ALV data in memory after using SUBMIT in a standard report.
The code for the above is:
REPORT ztest1.
FIELD-SYMBOLS <lt_pay_data> TYPE ANY TABLE.
DATA lr_pay_data TYPE REF TO data.
cl_salv_bs_runtime_info=>set(
EXPORTING display = abap_false
metadata = abap_false
data = abap_true ).
SUBMIT rfts7000
AND RETURN.
TRY.
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING r_data = lr_pay_data ).
ASSIGN lr_pay_data->* TO <lt_pay_data>.
CATCH cx_salv_bs_sc_runtime_info.
MESSAGE `Unable to retrieve ALV data` TYPE 'E'.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
When it is run the program rfts7000 runs and prompts for data selection.
After submitting the selection screen i get:
ST22 extract:
Any ideas?
After some research based on comments in the relative SCN Question the case is as follows.
The system is throwing this error in order to prevent me from running outdated and obsolete (or soon to be obsolete) programs.
The specific program that i call through SUBMIT, is part of the Cash Management (CM) module which although is still active in S4/HANA , i think that is going to be replaced.
So SAP Note 2392358 says exactly that: "According to the S/4HANA Simplification List, the totals tables of classic CM are completed eliminated and therefore they shall not be accessed any more."
In order for this protection to work, SAP has a blacklist where the programs are listed in order not to be used.
But there is a possible "backdoor" to that as explained in SAP Note 2249880. The backdoor is just a way to remove a program from the Blacklist.
The note suggests to get approval from SAP first and then to follow the steps to remove the program from the blacklist.
As a side note, i worry more that we have implemented cash management in an outdated module rather than worrying about the error after all...

Detect if printer support duplex programmatically using obj-c

I have been stumped by this for the last few days. I need to detect if a printer support duplex printing.
I have had partial success using code like:
NSPrinter * printer = [NSPrinter printerWithName:pname];
[printInfo setPrinter:printer];
PMPrintSettings settings = printInfo.PMPrintSettings;
PMDuplexMode pmDuplexMode = 0;
OSStatus status = PMGetDuplex(settings, &pmDuplexMode);
supportsDuplex = (status >= 0);
But this only work if I captured a full printerConfig through an NSPrintPanel. What I need is a way to detect if a printer with a specific name support duplex without requiring the user to 1st open a panel. I would like to do if for any printer defined on the local Mac. Any help is appreciated!
In your code snippet, I doubt that it's correct to interpret positive status as indicating support. In general, any value other than zero (noErr) is a failure of some sort.
If you're confident that PMGetDuplex() returns an error for a print settings object when the printer doesn't support duplex, you can try this approach: create a session with PMCreateSession(), obtain a PMPrinter using PMPrinterCreateFromPrinterID() or by searching the array returned from PMSessionCreatePrinterList() for on which matches whatever criteria you want, set the session to use that printer using PMSessionSetCurrentPMPrinter(), create a print settings object with PMCreatePrintSettings(), call PMSessionDefaultPrintSettings() to initialize the print settings from the session, call PMSessionValidatePrintSettings() just for good measure, then call PMGetDuplex() and check the return value.
It might also be worth trying to set a duplex mode with PMSetDuplex() and check the return code and, possibly, calling PMSessionValidatePrintSettings() and checking if it changed that setting.

Maven an java.io.scanner(System.in)

I'm running into issues with my project. When running in Netbeans it seems to work fine with user interaction. However when I run using mvn test it does not. I see the command line menu but I am not prompted to make a selection. When I force terminate the project, I get an error about No Line Found.
Any Ideas? I'm stumped.
The line that isn't working is essentially:
System.out.print("1) Print String\n"
+ "0) Exit\n"
+ "Enter Selection: ");
String line = (new java.util.Scanner(System.in)).nextLine();
I see the output Similar to this:
1) Print String
0) Exit
But I don't see "Enter Selection: " and it doesn't prompt for the String input. I terminate and get "No Line Found" though after I cancel the execution I see the whole string int he "Test Results window".
It's abnormal for unit tests to pause for user interaction. I wouldn't be surprised if it acts strangely. I expect the testing libraries don't really anticipate this sort of thing.
In practice, one should not interact with user while performing JUnit tests. Tests should be designed to operate automatically and continuously. If you want to test underlying code with two separate values, two tests should be implemented and call each the underlying code with their own value. This should cover for the two options offered to your user.

DB Query no longer recognizes SQL parameters in existing application when debugging in VS2010

I just started working with an application that I inherited from someone else and I'm having some issues. The application is written in C# and runs in VS2010 against the 3.5 framework. I can't run the application on my machine to debug because it will not recognize the way they referenced their parameters when writing their DB queries.
For instance wherever they have a SQL or DB2 query it is written like this:
using (SqlCommand command = new SqlCommand(
"SELECT Field1 FROM Table1 WHERE FieldID=#FieldID", SQLconnection))
{
command.Parameters.AddWithValue("FieldID", 10000);
SqlDataReader reader = command.ExecuteReader();
...
If you will notice the "parameters.AddWithValue("FieldID", 10000);" statement does not include the "#" symbol from the original command text. When I run it on my machine I get an error message stating that the parameter "FieldID" could not be found.
I change this line:
command.Parameters.AddWithValue("FieldID", 10000);
To this:
command.Parameters.AddWithValue("#FieldID", 10000);
And all is well... until it hits the next SQL call and bombs out with the same error. Obviously this must be a setting within visual studio, but I can't find anything about it on the internet. Half the examples for SQL parameter addition are written including the "#" and the other half do not include it. Most likely I just don't know what to search for.
Last choice is to change every query over to use the "#" at the front of the parameter name, but this is the transportation and operations application used to manage the corporation's shipments and literally has thousands of parameters. Hard to explain the ROI on your project when the answer to the director's question "How's progress?" happens to be "I've been hard at it for a week and I've almost started."
Has anyone run into this problem, or do you know how to turn this setting off so it can resolve the parameter names without the "#"?
Success! System.Data is automatically imported whenever you create a .NET solution. I removed this reference and added it back to make sure that I had the latest version of this library and that fixed the issue. I must have had an old version of this library that was originally pulled in... only thing I can figure.
Its handled by the .NET Framework data providers not Visual Studio.
It depends on the data source. Look here:Working with Parameter Placeholders
You can try working with System.Data.Odbc provider and using the question mark (?) place holder. In thios case dont forget to add the parameters in the same order they are in the query.

I would like to extract the SQL queries from Crystal Report .rpt files, is there a way to do this?

I would like to extract the SQL queries from Crystal Report .rpt files, is there a way to do this?
I don't have any of the Crystal Reports products, just the .rpt files.
Here's a .Net example of code that grabs the Command Sql from all Crystal Reports in a given directory. It requires the Crystal 2008 .Net SDK to be installed (you can download a trial from SAP):
foreach (string file in Directory.GetFiles("c:\\projects\\Reports", "*.rpt"))
{
Console.WriteLine(String.Format("Processing {0}...", file));
var doc = new CrystalDecisions.CrystalReports.Engine.ReportDocument();
doc.Load(file);
foreach (dynamic table in doc.ReportClientDocument.DatabaseController.Database.Tables)
{
if (table.ClassName == "CrystalReports.CommandTable")
{
string commandSql = table.CommandText;
//TODO: do something with commandSql
}
}
}
To get the SQL as Crystal would build it when running a report, see this link: SAP Note 1280515 - How to extract SQL query from Crystal reports using RAS sdk.
I believe to do this, you need to supply the report parameter values so that Crystal can connect to the database in order to build the SQL. In the example, since a Report Viewer control is used, Crystal can prompt the user for the parameters.
In "Crystal Reports ActiveX Designer Design and Runtime Library" (craxddrt.dll), the Report.SQLQueryString property will do what you want.
I can't seem to find an equivalent property in the .Net SDK, and believe me, I've been looking.
** edit **
It appears that one can make use of the In-Process RAS Server to get this information:
CrystalDecisions.ReportAppServer.DataDefModel.CommandTableClass.CommandText
The other way around this is if you can run the reports, you can hook up SQL Profiler to your DB and capture the incoming SQL on the database side.
JoshL's answer worked for several of my reports, but not all of them. The following method, using ReportClientDocument.RowsetController.GetSQLStatement, was able to extract some of the queries that the other method missed.
foreach (string file in Directory.GetFiles("c:\\projects\\Reports", "*.rpt"))
{
Console.WriteLine(String.Format("Processing {0}...", file));
var doc = new CrystalDecisions.CrystalReports.Engine.ReportDocument();
doc.Load(file);
var controller = doc.ReportClientDocument.RowsetController;
var groupPath = new CrystalDecisions.ReportAppServer.DataDefModel.GroupPath();
string temp = String.Empty;
string commandSql = controller.GetSQLStatement(groupPath, out temp);
//TODO: do something with commandSql
}
My experience is with older versions of Crystal (8,9) - I've no idea what the file formats look like for more recent versions. However, it's worth opening the files up in a text editor just in case, but for the file formats I've seen, the query text is not accessible this way.
If I remember correctly, some versions of Visual Studio 2003 came with tools for manipulating Crystal .rpt files (but I guess this isn't of much use to you, since if you had this already, you wouldn't be asking!).
It's not a very imaginative suggestion, but perhaps your quickest route would be to download the 30-day trial version of the current Crystal Reports, and see if that will open the files for you.
In the Visual studio, select the .rpt file and Go to field explorer, right click on DatabaseFields. Click on SQL query option to view the query.