I am building a BIRT report based on a dynamic table. I have a function that needs to return a table with variable number of columns of different types, so we have decided that this function will create a temporary table and just return its name.
So in the BIRT beforeFactory I am running the query that calls this function and then I am trying to read from the table of returned name and create a report table dynamically based on the number of columns and types. Two questions:
1. Is there a better way to return a table with variable number of columns? (this cannot be all the possible columns that I later filter as that would exceed maximum number of allowed columns)?
2. How to make Birt to see my temporary table? Here is the code, that I run in beforeFactory. Apparenty the table does not exists when calling second query.
importPackage(Packages.java.lang);
importPackage(Packages.org.eclipse.birt.report.data.adapter);
importPackage(Packages.org.eclipse.birt.report.data.adapter.api);
importPackage(Packages.org.eclipse.birt.report.data.adapter.impl);
importPackage(Packages.org.eclipse.birt.report.model.api);
importPackage(Packages.org.eclipse.birt.data.engine.api.querydefn);
//Get Data Source
var dataSource =
reportContext.getDesignHandle().getDesign().findDataSource("mydb");
//Create Data Set for data table name
var elementFactory =
reportContext.getReportRunnable().designHandle.getElementFactory();
var dataSet = elementFactory.newOdaDataSet("tableName",
"org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet");
dataSet.setDataSource(dataSource.getName());
dataSet.setQueryText("select table_name from my_export_function('str1',
'str2');");
reportContext.getDesignHandle().getDataSets( ).add(dataSet);
//Create Data Session
var myconfig =
reportContext.getReportRunnable().getReportEngine().getConfig();
var des = DataRequestSession.newSession(myconfig, new DataSessionContext(3));
var dset = reportContext.getDesignHandle().findDataSet("tableName");
des.defineDataSource(des.getModelAdaptor()
.adaptDataSource(reportContext.getDesig nHandle()
.findDataSource("mydb")));
des.defineDataSet(des.getModelAdaptor()
.adaptDataSet(reportContext.getDesignHandle()
.findDataSet("tableName")));
//Query Definition
queryDefinition = new QueryDefinition();
queryDefinition.setDataSetName(dataSet.getName());
queryDefinition.setAutoBinding(true);
var pq = des.prepare(queryDefinition);
var qr = pq.execute(null);
var ri = qr.getResultIterator();
var tableName = "";
while (ri.next()) {
tableName = ri.getString("table_name");
}
var dataSet2 = elementFactory.newOdaDataSet("reportData",
"org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet");
dataSet2.setDataSource(dataSource.getName());
dataSet2.setQueryText("select * from " + tableName + ";");
System.out.println("TTTT: " + dataSet2.getQueryText());
reportContext.getDesignHandle().getDataSets( ).add(dataSet2);
//Query Definition
queryDefinition2 = new QueryDefinition();
queryDefinition2.setDataSetName(dataSet2.getName());
queryDefinition2.setAutoBinding(true);
var pq2 = des.prepare(queryDefinition2);
var qr2 = pq2.execute(null);
var ri2 = qr2.getResultIterator( );
var cc = ri2.getResultMetaData().getColumnCount();
System.out.println("col_01_name: " +
ri2.getResultMetaData().getColumnLabel(1));
System.out.println("Count: " + cc);
while (ri2.next()) {
System.out.println("Table: "+ ri2);
System.out.println("col_01: "+ ri2.getValue("col_01"));
}
ri.close();
qr.close();
ri2.close();
qr2.close();
des.close();
I managed to make the code work. Following lines solved the problem with second query:
var des2 = DataRequestSession.newSession(myconfig, new DataSessionContext(3));
des2.defineDataSource(des2.getModelAdaptor()
.adaptDataSource(reportContext.getDesig nHandle()
.findDataSource("mydb")));
des2.defineDataSet(des2.getModelAdaptor()
.adaptDataSet(reportContext.getDesignHandle()
.findDataSet("tableName")));
and then:
var pq2 = des2.prepare(queryDefinition2);
Also we have changed the function to return the query instead of creating a temporary table.
Related
I am new to spreadsheets and in need of an Apps Script that triggers an Email every time a row is added, which also gives what has been added(the entire row). I have found many scripts written but none of them work for me.
I finally found a code that works but only partially: The issue is, I do not get data that is pasted in the row (pasting data multiple cells at a time) and data also comes from another automatic source like forms, and does not always enter by a user. in that case, the data comes as undefined. But when I manually enter the data I get the email.
Can anybody help me with this?
function emailChange(e) {
var range = e.range;
var spreadSheet = e.source;
var sheetName = spreadSheet.getActiveSheet().getName();
var spreadsheetName = SpreadsheetApp.getActiveSpreadsheet().getName();
var column = range.getColumn();
var row = range.getRow();
var inputValue = e.value;
var oldValue = e.oldValue;
var user = e.user;
var table = "<table border=1 cellpadding=5px >";
table = table + "<tr><td>File Name</td><td>"+spreadsheetName+"</td></tr>";
table = table + "<tr><td>Sheet Name</td><td>"+sheetName+"</td></tr>";
table = table + "<tr><td>Column</td><td>"+column+"</td></tr>";
table = table + "<tr><td>Row</td><td>"+row+"</td></tr>";
table = table + "<tr><td>Old Value</td><td>"+oldValue+"</td></tr>";
table = table + "<tr><td>Input Value</td><td>"+inputValue+"</td></tr>";
table = table + "<tr><td>User</td><td>"+user+"</td></tr>";
table = table + "<tr><td>Modified</td><td>"+new Date()+"</td></tr>";
table = table + "</table>";
MailApp.sendEmail({
to: "", //Enter Email Address to Send Email
subject: spreadsheetName + " - Change",
htmlBody: table
});
}
I have a DB source which I am transforming into HL7. In the transform, I have a step to connect to the database and retrieve rows for OBX segments, there can be no rows or multiple rows.
I'm successfully getting all the values, but I'm having trouble getting them written into OBX segments. They're all the same, and all the last row retrieved.
Database values:
OBX3 OBX5
Test123 This is a new referral
Test456 Person
Test789 Anxiety
The result I'm getting in the message is:
OBX|0||Test789||Anxiety
OBX|1||Test789||Anxiety
OBX|2||Test789||Anxiety
Code:
var erefID = msg['erefid'].toString();
var dbConn = DatabaseConnectionFactory.createDatabaseConnection(driver,address,username,password);
var sql = "SELECT OBX3,OBX5 from table where column =" + erefID;
var results = dbConn.executeCachedQuery(sql);
var resultSize = results.size();
logger.info('query results ' + results);
logger.info('result size ' +resultSize);
var obx3 = "";
var obx5 = "";
while(results.next()){
var i=0
obx3 = results.getString(1);
logger.info('obx3 ' + obx3);
obx5 = results.getString(2);
logger.info('obx5 '+obx5);
while(i<resultSize)
{
createSegment('OBX', tmp,i);
tmp['OBX'][i]['OBX.1']['OBX.1.1'] = i;
tmp['OBX'][i]['OBX.3']['OBX.3.1'] = obx3;
tmp['OBX'][i]['OBX.5']['OBX.5.1'] = obx5;
i++;
}
}
dbConn.close();
Switched around the while statements, works now
while(i<resultSize){
var i=0
obx3 = results.getString(1);
logger.info('obx3 ' + obx3);
obx5 = results.getString(2);
logger.info('obx5 '+obx5);
while(results.next()){
createSegment('OBX', tmp,i);
tmp['OBX'][i]['OBX.1']['OBX.1.1'] = i;
tmp['OBX'][i]['OBX.3']['OBX.3.1'] = obx3;
tmp['OBX'][i]['OBX.5']['OBX.5.1'] = obx5;
i++;
}
}
I am working on AngularJs application testing framework where I am using Protractor. I want to read the data (urls, usernames, passwords) from an excel sheet. I am using the following code but it's showing me errors.
Please find the below code:
var Excel = require('exceljs');
var wrkbook = new Excel.Workbook();
wrkbook.xlsx.readFile('E:\\Login_Data.xlsx').then(function()
{
var worksheet = wrkbook.getWorksheet('Sheet1');
worksheet.eachRow(function (Row, Test_URL)
{
console.log("Row " + Test_URL + " = " + JSON.stringify(Row.User_Name));
});
});
The data from excel sheet is :
Test_URL User_Name Password
http://...com abc#1111 xyz#333
Please let me know your positive inputs so that I can run my code and proceed forward.
Thanks in advance
eachRow isn't getting the Test_URL variable that you set as function parameter; that is instead the row index.
For getting every value of the row, you can use Row.values, and also you could the value of each Cell (corresponding to that row) with .getCell.
So it should be something like this:
var Excel = require('exceljs');
var wrkbook = new Excel.Workbook();
wrkbook.xlsx.readFile('E:\\Login_Data.xlsx').then(function()
{
var worksheet = wrkbook.getWorksheet('Sheet1');
worksheet.eachRow(function (Row, rowIndex)
{
var test_url = Row.getCell(1).value;
var user_name = Row.getCell(2).value;
var password = Row.getCell(3).value;
// do whatever you want with those variables.
});
});
So I tried this but it didn't work (on isServer) :
var tableName= "";
(...)
if (silly_cond === 1){
tableName = "Table1";
}else{
tableName = "Table2";
}
TableCol = new Mongo.Collection(tableName);
For some reason I can't get it to work. It seems to only accept
TableCol = new Mongo.Collection("Table1");
The idea was to fetch the tablename from the table ID, and apply the same JS to different tables (on different templates). What am I doing wrong?
You need to declare tableName outside the functions, otherwise it can't be seen.
var tableName = "";
if (silly_cond === 1){
tableName = "Table1";
}else{
tableName = "Table2";
}
TableCol = new Mongo.Collection(tableName);
I ended up using the dburles:mongo-collection-instances package. It let's me access any collection by the collection name. So in my example:
TableCol = new Mongo.Collection("Table1");
Using the above package I just write for example:
var dbvar = "Table1";
Meteor.Collection.get(dbvar).find()
and this way I can use variables to get collections.
I have this reusable pattern to create a table, inspired by http://bl.ocks.org/3687826, and I have two questions about it.
This is the function:
d3.table = function(config) {
var columns = [];
var tbl = function(selection) {
if (columns.length == 0) columns = d3.keys(selection.data()[0][0]);
console.log(columns)
// Creating the table
var table = selection.append("table");
var thead = table.append("thead");
var tbody = table.append("tbody");
// appending the header row
var th = thead.selectAll("th")
.data(columns)
th.enter().append("th");
th.text(function(d) { return d });
th.exit().remove()
// creating a row for each object in the data
var rows = tbody.selectAll('tr')
.data(function(d) { return d; })
rows.enter().append("tr");
rows.attr('data-row',function(d,i){return i});
rows.exit().remove();
// creating a cell for each column in the rows
var cells = rows.selectAll("td")
.data(function(row) {
return columns.map(function(key) {
return {key:key, value:row[key]};
});
})
cells.enter().append("td");
cells.text(function(d) { return d.value; })
.attr('data-col',function(d,i){return i})
.attr('data-key',function(d,i){return d.key});
cells.exit().remove();
return tbl;
};
tbl.columns = function(_) {
if (!arguments.length) return columns;
columns = _;
return this;
};
return tbl;
};
This table can be called as follows:
/// new table
var t = d3.table();
/// loading data
d3.csv('reusable.csv', function(error,data) {
d3.select("body")
.datum(data.filter(function(d){return d.price<850})) /// filter on lines
.call(t)
});
where the reusable.csv file is something like this:
date,price
Jan 2000,1394.46
Feb 2000,1366.42
Mar 2000,1498.58
Apr 2000,1452.43
May 2000,1420.6
Jun 2000,1454.6
Jul 2000,1430.83
Aug 2000,1517.68
Sep 2000,1436.51
and the number of columns can be updated by
t.columns(["price"]);
d3.select("body").call(t);
The problem is that another table with thead and tbody is created while updating, because the creation of the table is inside the function.
How can I say "create the table only one time, then update"?
Another question is: how can I filter the lines using a method inside the function?
The problem is with these three lines of code:
// Creating the table
var table = selection.append("table");
var thead = table.append("thead");
var tbody = table.append("tbody");
which always appends new table, thead, and tbody elements to your document. Here's how you can do this conditionally, only when these elements don't already exist (the example you cite creates its div.header element similarly):
selection.selectAll('table').data([0]).enter().append('table');
var table = selection.select('table');
table.selectAll('thead').data([0]).enter().append('thead');
var thead = table.select('thead');
table.selectAll('tbody').data([0]).enter().append('tbody');
var tbody = table.select('tbody');
The selectAll().data([0]).enter().append() pattern conditionally creates a single element if it isn't found. The cited example used data([true]) but any array with a single element will do.
To filter the nested data from within your function, change your call to data() and pass a filtered subset of the selection data like this:
var rows = tbody.selectAll('tr').data(tbody.data()[0].filter(function(d) {
return d.price > 1400;
}));
Good luck!