I have 10 rows of data on my input step, i transform them in a for-loop and i should get more than 10 rows, but in this case i get the last transform of each iteration that the loop have for each data
I tried to use appendToFile() but the result data is not useful and pentaho read it as a unique header
On my alert() method i can see that the for loop transform the data.
var PERIODO = 2
var i
var fecha_final
//var ruta_acess ="D:\TEST.accdb"
//var contenido
////var contenido2
//var arreglo_completo
for (i=0; i<=PERIODO; i++){
fecha_final = dateAdd(FECHA_INICIO,"d",i)
Alert(i)
}
As I show in the below photo i get only 10 records and in the other photo appears the result that i want that are the results data of each iteration of the for-loop
Modified JavaScript value photo:
Expected result:
Obtained result:
For loops are not really a thing in PDI. Transformations work on sets of rows that flow through the steps, so it's best for performance and stability to use that mindset.
In your scenario each incoming row should end up as three copies, but with different calculated values based on a single new field (with values 0,1,2).
The way to do this in PDI is with a Join rows (cartesian product) step. It takes two sets of input rows and outputs a row for every combination of input rows, possibly filtered by defining a key field that has to match. So if you have 10 rows in the main input and 3 rows in the second, it will output 30 rows.
You will first need to create a data grid as the second input. Define a single integer field, name it something clear and on the second tab fill three rows with 0, 1 and 2 respectively.
Connect both inputs to the Join rows step. You don't need to configure any matching key.
The output of the Join step will be three rows for each input row, one with each of the values 0, 1, 2. Connect that output to a Calculator step and use the calculation Date A + B days to replace the logic from your javascript step.
what i mean is that in the obtained result photo the "i" variable only shows the value of "3" and i would like to have "1", "2" and "3"
to solve this i used
var row = createRowCopy(getOutputRowMeta().size())
var idx = getInputRowMeta().size()
row[idx++] = DPROCESS
this add a row for each result of the iteration.
before the tranformation result showed to me only the last value of each loop.
Related
So if I have a Javascript array of strings, how do I append each element to a row in the Postgres text[] column? This is what I'm currently using, but it's not yielding the desired result (which is just making the text array in the column of {"1","2","3"}.
let addNumbers = 'UPDATE numTable SET column1 = array_append(columnName, ($1)) WHERE uid = ($2)'
let x = ["1","2","3"]
I'm querying to the db with
query(addNumbers, [x, uid]);
I've tried using array_append but this results in the column getting a value of
{"{\"1\",\"2\",\"3\"}"}
I'd prefer not to iterate and append each one individually because this'll obviously increase the number of database calls--any help is much appreciated!
I'm trying to find the index of a value in an array. The array is a spreadsheet, and I want to search down the rows till it finds the value in the active cell and returns the row number/index.
I have tried this searching across columns and it works fine, but when trying to search down rows it does something I can't quite figure out.
var datass =SpreadsheetApp.getActiveSpreadsheet().getSheetByName('####')
var actCell = ss.getActiveCell()
var name =datass.getRange(3,2,datass.getLastRow(),1).getValues();
var nameIndex = name[0].indexOf(actCell.getValue)
nameIndex always returns -1 unless name[#]is the right index number. even if I omit a # it returns -1.
logger.log(name) shows that the pulled is corrected but because of the way it pulls the data index only searches on []
it shows as:
[[##], [##], [##]]
when this functions correctly searching along columns instead of rows, the log shows as
[##,##,##,##]
how do can I search down my list and get the row number based off the value in my active cell?
(Option 1)
As what was mentioned by #Cooper, you can use Range.createTextFinder(findText) to search for a specific string within your selected range.
(Option 2)
You can convert your 2-d array to 1-d array to be able to search for a specific value using Array.prototype.indexOf()
Sample Code:
var datass =SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet15");
var actCell = datass.getActiveCell();
var rowStart = 3;
var name =datass.getRange(rowStart,2,datass.getLastRow()-2,1).getValues().flat();
Logger.log(name);
Logger.log(actCell.getA1Notation());
Logger.log(actCell.getValue());
var nameIndex = name.indexOf(actCell.getValue());
Logger.log("match found at row: "+(rowStart+nameIndex));
What it does?
Select a sheet and get its active cell.
Get the values of a given range. This will return a 2-d array values. Convert it to 1-d array using Array.prototype.flat(). Your array will be from this [[##], [##], [##]] to [##,##,##]
Use Array.prototype.indexOf() to search for a value within the array.
Note:
When you select the range of values, you start at row3. To get the actual row index of the matched value you also need to add an offset 3 to the index found in your name array
Output:
4:59:23 AM Notice Execution started
4:59:24 AM Info [A, B, C, D, E, F, G]
4:59:24 AM Info A1
4:59:24 AM Info D
4:59:24 AM Info match found at row: 6
4:59:24 AM Notice Execution completed
Hi Helpful Contributors,
I have a gform where user can select more than 1 answer. In response sheet, we will see the multiple answers will be printed in one cell of a column separated by comma. For that matter, I have some calculation to do on each answer. So, I was thinking to declare each input separated by comma as an array value so that I can then refer each value by it's index number in that array. Is this possible?
Below is my code that I tried but when I tried to refer back to that array on index[0], the output is still all the values in that same cell, so I think all are still kept as 1 value of array.
function mytest(){
var sheet=SpreadsheetApp.getActiveSheet();
var input=[];
var extraitem=sheet.getRange(lastorder,77).getValue(); //this cell keeps the multiple answers : "Change of address, Change of mobile no., Change of vehicle type, Change of license type"
input.push(extraitem.split(','));
Logger.log("myinput :"+input[0]); // check the value in position 0 is the first among the multiple answers
}
Please correct my code. Thank you in advance.
The issue with your code is that you push an array extraitem.split(',') into another array input=[]. As a result, input[0] is the full array extraitem.split(',').
To get the first element of the extraitem.split(',') array you can do Logger.log(input[0][0]) or (preferably) simply ignore the push part:
function mytest(){
var sheet=SpreadsheetApp.getActiveSheet();
var extraitem=sheet.getRange(lastorder,77).getValue();
var input= extraitem.split(',');
Logger.log("myinput :"+input[0]);
}
Demonstration:
const extraitem = "Change of address, Change of mobile no., Change of vehicle type, Change of license type";
const input = extraitem.split(',');
console.log("myinput :" + input[0]);
Within Oracle APEX v4.2.2, I have a simple classic report that has as a first column, a checkbox f50 setup attached to the table's ID column, which will allow a user to check all or specific rows and remove these records from the report/table.
An example report might be something like:
ID Col2 Col3 Col4
----------------------------
1 10 20 30
2 5 8 9
3 92 88 12
4 1 2 44
5 95 77 88
The requirement I am after is that I want to perform this whole process of checking the IDs and the removal of these records done without having to submit the whole page but would like it done via an AJAX method using apex.process.server if possible.
UPDATE: Just a bit more background on this requirement based on the report I am attempting to hook this apex.process.server checkbox IDs, i.e.:
ID Report Column above within Report Attributes heading looks like this:
<input type="checkbox" label="Select Code" onclick="$f_CheckFirstColumn(this)" />
Drilling down into this ID column under HTML Expression is the following:
<input type="checkbox" #ID# value="#ID#" name="f50" id="f50_#ROWNUM#"/>
Region Source:
SELECT A.ID,
A.REQ_NO COL2,
A.CODE_ID||apex_item.hidden(20, A.CODE_ID)||apex_item.hidden(30, A.ID) COL3,
GROUP_VALUE COL4
FROM MY_TABLE A
WHERE A.REQ_NO = :REQ_NO
I believe inorder to have APEX store the values within the apex_application.g_f50.countarray of the IDs to be removed, the page needs to be submitted.
Using apex.process.server, can the ids, as they are checked, be passed as a JavaScript array to an on demand process that will then use these ids to perform the required delete operation?
How can I achieve the above via an AJAX means (no page refresh at all)?
Given this query for a report
select
"EMPNO",
"ENAME",
apex_item.checkbox2(2, 0) check1,
apex_item.checkbox2(3, 0) check2,
apex_item.checkbox2(4, 0) check3
from EMP
With EMPNO set to "Hidden" - so it'll generate a hidden input item appended to the last column.
To update a certain record you'll need a PK and a value to update the row with. That is why I'm using EMPNO. I'll pass that to the on-demand process.
function selectorToArray(pSelector){
function getVal(pNd){
switch ( pNd.nodeName ) {
case "INPUT":
switch ( pNd.type ) {
case "checkbox":
return $(pNd).prop("checked");
break;
default:
return $(pNd).val();
};
break;
default:
return $(pNd).val()
};
};
var lArray = [];
$(pSelector).each(function(){
lArray.push(getVal(this));
});
return lArray;
};
The function selectorToArray will fetch the values for the given selector to an array and get the value. As you might know, you can pass values to a process with x01, x02, ... But there are also arrays: f01, f02,...
With the following code you can send values over to the ondemand process:
function sendCheckboxes(){
var lf01 = [], lf02 = [], lf03 = [], lf04 = [];
lf01 = selectorToArray("input[name=f01]");
lf02 = selectorToArray("input[name=f02]");
lf03 = selectorToArray("input[name=f03]");
lf04 = selectorToArray("input[name=f04]");
apex.server.process("PROCESS_CHECKBOXES", {f01: lf01, f02: lf02, f03: lf03, f04: lf04});
};
You can use those just like you would otherwise: loop over them:
DECLARE
l_pk VARCHAR2(30);
l_check1 VARCHAR2(30);
l_check2 VARCHAR2(30);
l_check3 VARCHAR2(30);
BEGIN
-- f01: PK
-- f02: checkbox values column1
FOR i IN 1..apex_application.g_f01.count
LOOP
l_pk := apex_application.g_f01(i);
l_check1 := apex_application.g_f02(i);
l_check2 := apex_application.g_f03(i);
l_check3 := apex_application.g_f04(i);
apex_debug.message('Record with PK '||l_pk||': check1? '||NVL(l_check1, 'NO')||': check2? '||NVL(l_check2, 'NO')||': check3? '||NVL(l_check3, 'NO'));
END LOOP;
END;
In your code, there are 3 item arrays: f20, f30 and f50. f30 holds the row PK value, while f50 is used for the checkbox.
Don't be fooled by the array naming. Apex itself uses the f## arrays for submission, true enough. And your items with name f50 will indeed be in array g_f50 on page submit.
You can however also use arrays f01 to f20 (don't think it goes up to 50) for ajax calls! They're a great addition to the variables x01-x20!
When using the arrays to send a bulk of values to your process, instead of one-by-one, I think it's most useful to not just send an array of PK values, with a position-matched array of values to interact with. This isn't as valuable when you use a report without pagination though, but still. With pagination, the idea is that you don't really know what set of data was just interacted with. Of 100 records, 10 rows were presented. Of those 10 rows, 6 were checked on render, and on submit only 5 are. Which ones are checked and which ones are unchecked. Knowing which 5 are checked doesn't mean you know the unchecked ones.
When you include a PK column however, you'll always have those 10 rows and you're able to identify clearly which records has been checked or unchecked.
For instance, 10 records in your report will (=should!) mean that 10 values are put in an array (eg l_f01) with the PK value and 10 more values are put in another array (eg l_f02) with eg a checked indicator. So when passing those on to the on-demand process, you'll be able to loop over array f01 reliably, and fetch the checked or unchecked indicator from array f02 with your current index variable used for f01.
Plainly put, you're building up 2 arrays with this sort of value set:
f01 - IDs | f02 - checkeds
----------|---------------
4520 | false
4521 | true
4527 | false
4561 | true
4578 | true
I need help with a loop... it's probably simple but I'm having difficulty coding it up.
Basically, I need to check existing Ids for their number so I can create a unique id with a different number. They're named like this: id="poly'+i'" in sequence with my function where i is equal to the number of existing elements. Example: Array 1, Array 2, Array 3 corresponding with i=1 for the creation of Array 1, i=2 for Array 2, etc.
Right now i is based on the total number of existing elements, and my "CreateNew" function is driven off x=i+1 (so the example above, the new element will be named Array 4). The problem is that if you delete one of the middle numbers, the "Create" function will duplicate the high number. i.e. Array 1, 2, 3 delete 2, create new-> Array 1, 3, 3.
I need an if() statement to check if the array already exists then a for() loop to cycle through all i's until it validates. Not sure how to code this up.
The code I'm trying to correct is below (note I did not write this originally, I'm simply trying to correct it with my minimal JS skills):
function NewPanel() {
var i = numberOfPanels.toString();
var x = (parseInt(i)+1).toString();
$('#items').append('<div onclick="polygonNameSelected(event)" class="polygonName" id="poly'+i+'"> Array '+ x +' </div>');
$('div[id*=poly]').removeClass('selected');
$('#poly'+i).addClass('selected');
$('#poly'+i).click(function() {
selectedPolygon = i;
$('div[id*=poly]').removeClass('selected');
$(this).addClass('selected');
});
}
THANK YOU! :)
Please clarify "The problem is that if you delete one of the middle numbers, ". What do you mean by delete? Anyway, the simplest solution is to create two arrays. Both arrays will have the same created id's. Whenever an id is created in the first array, an id will be added to the second array. So when it is deleted from first array, check your second array's highest value and then create this id in first array. I hope this did not confuse you.
Well it is hard to tell why you cannot just splice the array down. It seems to me there is a lot of extra logic involved in the tracking of element numbers. In other words, aside from the index being the same, the ids become the same as well as other attributes due to the overlapping 1, 3, 3 (from the example). If this is not the case then my assumption is incorrect.
Based on that assumption, when I encounter a situation where I want to ensure that the index created will always be an appending one, I usually take the same approach as I would with a database primary key. I set up a field:
var primaryKeyAutoInc = 0;
And every time I "create" or add an element to the data store (in this case an array) I copy the current value of the key as it's index and then increment the primaryKeyAutoInc value. This allows for the guaranteed unique indexing which I am assuming you are going for. Moreover, not only will deletes not affect future data creation, the saved key index can be used as an accessor.