Create a Crystal Report with dynamic tables at runtime - sql

Hello I'm planning an application that is basically a reporting front-end for a database (proprietary Pervasive SQL) using an ODBC dsn-less connection string.
I am able to create the dataset in Visual Studio and link up the report(s) to the app. However in real world usage, the location of the database will be different per user. That is not the main problem. I overcame that with the connection string that allows you to set the location of the database path.
Here's the kicker...
The name of the tables that I want to read from are prefixed with a unique filename (actually the same name I mentioned above). I need crystal to re-map the table names at runtime. Just the table name prefixes really. The fields and names of the fields will not change.
Any ideas on where I should look for writing this block? I am using VS2010 & C# if that helps. I think thee should be some sort of class files that come with Crystal that can do some runtime reflection to get/set the table names?
Any thoughts would be welcome and appreciated.
Rob
Edit: I found some documents link that has API docs and other support. I will be studying them. They are all .chm files (Windows help files) so there is no "online" docs to search for.

Add a Crystal reportViewer change the name to objReport
add a public function ShowReport()
public void ShowReport(ReportDocument objReport)
{
Cursor.Current = Cursors.WaitCursor;
objReport.SetDatabaseLogon("", "dbpassword");
cRep.ReportSource = objReport;
this.Show();
Cursor.Current = Cursors.Default;
}
And Call it from anywhere in your application
ds = GetDataInDataSet();//fILL DataSet with your data
rptPSummary objRpt = new rptPSummary();
objRpt.SummaryInfo.ReportComments = "Have a nice day";
objRpt.SummaryInfo.ReportTitle = "Purchase Summary Report from " + sDate.ToString("dd/MM/yyyy") + " to " + eDate.ToString("dd/MM/yyyy");
objRpt.SetDataSource(ds);
frmReportView frmRpt = new frmReportView();
frmRpt.Text = objRpt.SummaryInfo.ReportTitle;
frmRpt.MdiParent = this;
frmRpt.ShowReport(objRpt);

Related

How do you get Endeca to search on a particular target field rather than across all indexed fields?

We have an Endeca index configured across multiple fields of email content - subject and body. But we only want searches to be performed on the subject lines. Endeca is returning matches within the bodies too. How do you limit the search to the subject?
You can search a specific field or fields by specifying it (them) with the Ntk parameter.
Or if you wish to search a specific group of fields frequently you can set up an interface (also specified with the Ntk parameter), that includes that group of fields.
This is how you can do it using presentation API.
final ENEQuery query = new ENEQuery();
final DimValIdList dimValIdList = new DimValIdList("0");
query.setNavDescriptors(dimValIdList);
final ERecSearchList searches = new ERecSearchList();
final StringBuilder builder = new StringBuilder();
for(final String productId : productIds){
builder.append(productId);
builder.append(" ");
}
final ERecSearch eRecSearch = new ERecSearch("product.id", builder.toString().trim(), "mode matchany");
searches.add(eRecSearch);
query.setNavERecSearches(searches);
Please see this post for a complete example.
Use Search Interfaces in Developer Studio.
Refer - http://docs.oracle.com/cd/E28912_01/DeveloperStudio.612/pdf/DevStudioHelp.pdf#page=209

Indexing Service empty filename property

I'm using the Windows Indexing Service for the first time and I need to return the doctitle and filename from the query.
My query is;
select doctitle, filename, vpath, rank, characterization from scope() where FREETEXT(Contents, '" & searchText & "') order by rank desc
I setup a fairly basic catalogue just pointing to a folder. I'm using this code from a website, the files are on the local machine and authentication shouldn't be a problem.
My search returns results but nothing in the filename property. The doctitle is populated but nothing else.
Thanks,
Mike
I know it's been a few months since this has been answered, but I'm currently using WIS on Windows Server 2008 R2 using C# and came across this on a search. Sometimes I can't take no for an answer, so I had scoured the internet and came up with this solution.
I'm sure you can convert the code as necessary, but...
You'll have to install the Windows Server 2003 File Services Indexing Service from the Server Manager's Roles.
For the catalog properties, I disabled the Inheritable Settings and set the WWW Server appropriately. I also generated 250 character abstracts to be stored in the Characterization column.
When I set up my catalog, I included/excluded certain folders of my web site's directory (include the site root) and when I queried it, I used the below SQL statement:
EDIT: Note the use of FREETEXT(Filename, '\""+q+"\"')) to query the name of the file
String fileTypes = "\".aspx\" OR \".doc*\" OR \".xls*\" OR \".ppt*\" OR \".txt\" OR \".pdf\" OR \".rtf\"";
String q = query.Text.Replace("'", "''");
sSqlString = "SELECT Filename, DocTitle, Size, VPath, Path, Rank, Write, Contents, Characterization ";
sSqlString += "FROM SCOPE() ";
sSqlString += "WHERE (CONTAINS(Contents, '\""+q+"\"') ";
sSqlString += "OR FREETEXT(Filename, '\""+q+"\"')) ";
sSqlString += "AND CONTAINS(Filename, '"+fileTypes+"') ";
sSqlString += "ORDER BY rank DESC, write DESC";
I create my connection using the using statement:
using(OleDbConnection conn = new OleDbConnection("Provider=MSIDXS.1;Data Source='"+catalog+"'"))
{
//your connection and data collection code here
}
One of the issues that I have run into is with certain filetypes. If the document creator didn't include a document title in their MS Office product, you won't get the DocTitle. If the pdf doesn't have any recognizable text in it and the document properties are not filled out, the docTitle and Content will be empty. The way I look at it, is if the business doesn't make their files 508 compliant, they won't show up in the results properly.
Here's a quick snippet of the ListView template that I am using.
<ItemTemplate>
<h3><%# Eval("DocTitle").ToString().Trim() == "" ? Eval("Filename").ToString().Split('.')[0] : ProperCase(Eval("DocTitle").ToString()) %></h3>
<p><span style="color:#0083be;">
<%# Request.ServerVariables["HTTP_HOST"].Length+vFilePath(Eval("Path")).Length > 100 ? (Request.ServerVariables["HTTP_HOST"]+vFilePath(Eval("Path"))).Substring(0,100)+"..." : Request.ServerVariables["HTTP_HOST"]+vFilePath(Eval("Path")) %></span><br />
<span style="color:#4d4e53"><%# String.Format("{0:MMMM dd, yyyy}",Eval("Write")) %> - </span>
<%# Eval("Characterization").ToString().Trim() == "" ? "..." : Eval("Characterization").ToString().Length == 250 ?
Eval("Characterization").ToString().Substring(0,250)+"..." : Eval("Characterization")%>
</p>
</ItemTemplate>
Since the docTitle in my case is used for the results header, I figured that if it's empty, I can take that empty string and replace it with the filename, minus the extention.
When making the query, make sure that you also properly use your meta tags using the keywords and description. This and the static content on the .aspx pages does get read by WIS. You'll note my use of Characterization to retrieve the contents.
This link provides instructions on setting up the W2k8 WIS along with vb.net code.
This link is a good source for the multitude of properties that can be queried and/or displayed.
I found the answer in this article;
http://support.microsoft.com/kb/954822
You cannot index Internet Information Services (IIS) Web sites in
Windows Server 2008 because of the design changes that were made to
IIS 7.0.
The successor or the Indexing Service is Windows Search.
Windows Search Wiki
Looks like I'm going to have to change the site to use Windows Search.

Excel "Refresh All" with OpenXML

I have an excel 2007 file (OpenXML format) with a connection to an xml file. This connection generates an excel table and pivot charts.
I am trying to find a way with OpenXML SDK v2 to do the same as the "Refresh All" button in Excel. So that I could automatically update my file as soon as a new xml file is provided.
Thank you.
Well there is quite good workaround for this.
Using OpenXML you can turn on "refresh data when opening the file" option in pivot table (right click on pivot table->PivotTable Options->Data tab).
This result in auto refresh pivot table when user first opens spreadsheet.
The code:
using (var document = SpreadsheetDocument.Open(newFilePath, true))
{
var uriPartDictionary = BuildUriPartDictionary(document);
PivotTableCacheDefinitionPart pivotTableCacheDefinitionPart1 = (PivotTableCacheDefinitionPart)uriPartDictionary["/xl/pivotCache/pivotCacheDefinition1.xml"];
PivotCacheDefinition pivotCacheDefinition1 = pivotTableCacheDefinitionPart1.PivotCacheDefinition;
pivotCacheDefinition1.RefreshOnLoad = true;
}
you need to determine "path" to yours pivotCacheDefinition - use OpenXML SDK 2.0 Productivity Tool to look for it.
BuildUriPartDictionary is a standard method generated by OpenXML SDK 2.0 Productivity Tool
protected Dictionary<String, OpenXmlPart> BuildUriPartDictionary(SpreadsheetDocument document)
{
var uriPartDictionary = new Dictionary<String, OpenXmlPart>();
var queue = new Queue<OpenXmlPartContainer>();
queue.Enqueue(document);
while (queue.Count > 0)
{
foreach (var part in queue.Dequeue().Parts.Where(part => !uriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString())))
{
uriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
queue.Enqueue(part.OpenXmlPart);
}
}
return uriPartDictionary;
}
Another solution is to convert your spreadsheet to macroenabled, embed there a VBA script that will refresh all pivot tables.
This can happen on button click or again when user opens spreadsheet.
Here you can find VBA code to refresh pivot tables:
http://www.ozgrid.com/VBA/pivot-table-refresh.htm
You can't do this with Open XML. Open XML allows you to work with the data stored in the file and change the data and formulas and definitions and such. It doesn't actually do any calculations.
Excel automation technically would work, but it's absolutely not recommended for a server environment and is best avoided on the desktop if at all possible.
I think the only way you can do this is following this type of method..
Save Open XML workbook back to a xlsx file.
Load the workbook using the Excel object model.
Call either
ThisWorkbook.PivotCaches(yourIndex).Refresh();
or
ThisWorkbook.RefreshAll();
although I was pretty sure RefreshAll would also work.
Use the object model to Save the workbook and close it.
Reopen for use with xml namespaces.
The solution provided by Bartosz Strutyński will only work if the workbook does contain pivot tables and they share the same cache. If the workbook does not contain pivot tables, the code will throw a NullPointerException. If the workbook contains pivot tables that use different caches (which is the case when data sources are different), only one group of pivot tables that use the same cache will be refreshed. Below is the code based on Bartosz Strutyński's code, free of the aforementioned limitation, and not relying on knowing the "path" of PivotCacheDefinition object. The code also inlines BuildUriPartDictionary, which allows avoiding enumeration of uriPartDictionary in case it’s not used somewhere else, and uses explicit types, to ease searching documentation for the used classes.
Dictionary<String, OpenXmlPart> uriPartDictionary = new Dictionary<String, OpenXmlPart>();
Queue<OpenXmlPartContainer> queue = new Queue<OpenXmlPartContainer>();
queue.Enqueue(document);
while (queue.Count > 0)
{
foreach (IdPartPair part in queue.Dequeue().Parts.Where(part => !uriPartDictionary.Keys.Contains(part.OpenXmlPart.Uri.ToString())))
{
uriPartDictionary.Add(part.OpenXmlPart.Uri.ToString(), part.OpenXmlPart);
queue.Enqueue(part.OpenXmlPart);
PivotTableCacheDefinitionPart pivotTableCacheDefinitionPart;
if ((pivotTableCacheDefinitionPart = part.OpenXmlPart as PivotTableCacheDefinitionPart) != null)
{
pivotTableCacheDefinitionPart.PivotCacheDefinition.RefreshOnLoad = true;
}
}
}

SQL code import into Access 2007

I basically need to know how to import SQL code into Access. I've tried one way but that requires me to do one table and one value at a time which takes a lot of time.
Can anyone help?
If you are trying to import data, rather than SQL code (see Duffymo's response), there are two ways.
One is to go where the data is and dump a .CSV file and import that, as Duffymo responded.
The other is to create a table link from the Access database to a table in the source database. If the two databases will talk to each other this way, you can use the data in the remote table as if it were in the Access database.
Well, some days ago I needed to shift data from an Access database to SQL (reverse of what you're doing). I found it simpler to write a simple script that would read data from my access database and insert it into SQL.
I don't think doing what you need to do is any different.
I don't know if it will help, but I posting my code (It's a simple C# function). You can just change the connections and it will work. Of course I only had 3 fields so I hard-coded them. You can do the same for your db schema.
protected void btnProcess_Click(object sender, EventArgs e)
{
//Open the connections to the access and SQL databases
string sqlDBCnn = #"Data Source=.\SQLEXPRESS;Integrated Security=True;AttachDBFileName=|DataDirectory|\mydb.mdf;user instance=true";
string accessDBCnn = #"Provider=Microsoft.Jet.OleDB.4.0;Data Source=C:\mydb.mdb";
OleDbConnection cnnAcc = new OleDbConnection(accessDBCnn);
cnnAcc.Open();
SqlConnection cnnSql = new SqlConnection(sqlDBCnn);
cnnSql.Open();
SqlCommand cmSql = new SqlCommand("DELETE tablename", cnnSql);
cmSql.ExecuteNonQuery();
//Retrieve the data from the Access Database
OleDbCommand cmdAcc = new OleDbCommand("SELECT * FROM tablename", cnnAcc);
OleDbDataReader drAcc = cmdAcc.ExecuteReader();
using (drAcc)
{
if (drAcc.HasRows)
{
//Loop through the access database records and add them to the database
while (drAcc.Read())
{
SqlCommand cmdSql = new SqlCommand("INSERT INTO tablename(Category, Head, Val) VALUES(#cat,#head,#val)",cnnSql);
SqlParameter parCat = new SqlParameter("cat",System.Data.SqlDbType.VarChar,150);
SqlParameter parHead = new SqlParameter("head",System.Data.SqlDbType.VarChar,150);
SqlParameter parVal = new SqlParameter("val",System.Data.SqlDbType.VarChar);
parCat.Value = drAcc["Category"].ToString();
parHead.Value = drAcc["Head"].ToString();
parVal.Value = drAcc["Val"].ToString();
cmdSql.Parameters.Add(parCat);
cmdSql.Parameters.Add(parHead);
cmdSql.Parameters.Add(parVal);
cmdSql.ExecuteNonQuery();
}
}
}
lblMsg.Text = "<p /> All Done Kapitone!";
}
SQL code? Or data? "one table and one value" makes me think it's the latter. If so, I'd suggest dumping the data out into a .csv file and importing that into Access tables.
Or maybe using a tool like Microsoft's DTS to map and move the data between sources. That would be the best idea.
I guess you are talking about "importing" both structure and data from SQL to ACCESS. ACCESS does not accept standard TSQL scripts that you could generate directly from your SQL Database. There are some commercial products like EMS that can more or less do the job for you. EMS has a data exporter module that can take your SQL data in different formats, including Access.
Another way would be to open an Access file and write some basic VBA code, taking advantage of the DoCmd.TransferDatabase method, where you can link OR copy tables from other databases into Access.
I forgot if these methods also allow the transfer of a 'clean' database model, including primary keys and relations... You'll have to give it a try.

Dynamic querystring in JRXML [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm trying to build a report that would be smart enough to modify slightly its sql query based on an input parameter of some sort.
For example if that special modifying parameter value is "1", it adds a field in the select and adds a group by clause to the query.
I've looked into java expressions, but they don't seem to be supported in the queryString tag of the jrxml. Also tried to make a variable containing the java expression and use that variable in the queryString tag... That didn't work either!
Right now I'm thinking of maybe have a stored procedure with all that logic and simply have the jrxml calling that stored procedure with the modifying input parameter, but the project I'm working on doesn't seem to have a whole lot of stored proc, so I'd like to see if there are other solutions before I go down that path.
Thanks for your help.
Thank you guys for your help, much apprieciated. However I found another way to go about it, and posted it for information: here
JasperDesign actually lets you modify portions of your jrxml document. So say you have a package "reports" where you store your report built either by hand or by a tool like iReport. As long as your query is defined in the tag <queryString> the following will work allowing you to change the query on the fly:
try {
String fileName = getClass().getClassLoader().getResource("com/foo/myproject/reports/TestReport.jrxml").getFile();
File theFile = new File(fileName);
JasperDesign jasperDesign = JRXmlLoader.load(theFile);
//Build a new query
String theQuery = "SLECT * FROM myTable WHERE ...";
// update the data query
JRDesignQuery newQuery = new JRDesignQuery();
newQuery.setText(theQuery);
jasperDesign.setQuery(newQuery);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
Connection conn = MyDatabaseClass.getConnection();
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, conn);
JasperViewer.viewReport(jasperPrint);
} catch (Exception ex) {
String connectMsg = "Could not create the report " + ex.getMessage() + " " + ex.getLocalizedMessage();
System.out.println(connectMsg);
}
With something like this you can create a member variable of your class that holds the new query and build it with whatever user constrains desired. Then at view time just modify the design.
-Jeff
I've done it using stored procedures which are just fine for these kinds of stuff. Otherwise you may switch to Java. Just grab the data from the database and according to the user provided parameters filter it, group it and send as a collection of beans to the Jasper report which will do the rendering.
JasperDesign helped me to solve the problem of building dynamic query on Jrxml file.
To build the Dynamic SQL, I was using the Squiggle(Google Code) to build the SQL dynamically.
Thanks jeff