Reading Form Responses over to dashboard based on 1 cell value - java

Thanks to all that answered my previous query, I have to be honest I really cannot get on with Google Apps Script :-(
What I am trying to do is relatively simple and for VBA on excel would be a doddle, but sheets is it's own beast I guess.
What I'd like to do is...
read in the form responses from a google form on the tab "Comments" Cells B2:H
Compare the unique key responses in column B on "Comments" with a unique key in A1 on tab "DashBoard"
If there are match I would like to add them onto the dashboard tab in Cells G3:M20
This would ultimately refresh everytime the dropdown in A1 on "Dashboard" is changed
The Data on responses is always 7 columns worth, varying from strings to dates. Sometimes G & H columns will be blank
Seriously any help is appreciated here, once I've got this done I don't have to touch Google Sheets anymore lol
function bnbm() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActive().getSheetByName("Comments");
var range = sheet.getRange("Comments!B2:H");
var values = range.getValues();
var values2 = values.filter(String);
var range2 = sheet.getRange("Dashboard!A1")
var rowd = range2.getValues();
var rowd2 = rowd.filter(String);
var result = sheet.getRange("Dashboard!G3:M20")
for (var i = 0; i < values2.length; i++) {
if (values2[i][0] == rowd2[0][0]) {
result.setValues(values2[i][1])
}
}
}

I don't think that your result array can be a fixed length since you Comment goes down sh.getLastRow() so this is what I think you want:
Using ranges like B2:H is not a good idea in Apps Script because they generate a lots of null data at the end of the range which has to be filtered out.
function bnbm() {
const ss = SpreadsheetApp.getActive();
const csh = ss.getSheetByName("Comments");
const dsh = ss.getSheetByName('Dashboard');
const vs = csh.getRange(2, 2, csh.getLastRow() - 1, 7).getValues();
const A1 = dsh.getRange("A1").getValue();
let oA = [];//matches array
for (let i = 0; i < vs.length; i++) {
//if column B Comments = Dashboard A1
if (vs[i][0] == A1) {
oA.push(vs[i]);//save current row in matches array
}
}
if ((dsh.getLastRow() - 2) > 0) {
dsh.getRange(3, 7, dsh.getLastRow() - 2, 7).clearContent();//clear contents if any
}
if (oA.length > 0) {
dsh.getRange(3, 7, oA.length, oA[0].length).setValues(oA);//move matches to dashboard
ss.toast(`${oA.length}`, 'Matches');//number of matches
} else {
ss.toast('No Matches', 'Matches', 10);//no matches
}
}
Sample Comment Data Set:
COL1
COL2
COL3
COL4
COL5
COL6
COL7
COL8
24
21
9
24
16
7
12
13
12
19
9
19
20
7
11
18
19
18
6
1
19
16
1
16
2
0
4
19
8
12
8
20
19
19
8
24
8
0
1
18
22
6
9
2
17
18
5
20
22
13
7
1
9
15
24
14
20
7
8
21
11
2
10
22
4
11
12
21
13
6
9
22
12
19
23
6
8
9
5
12
3
18
11
17
7
12
3
22
19
19
11
3
13
15
4
12
23
1
10
16
20
11
5
20
17
20
14
13
4
13
15
1
Results for Dashboard A1 = 19;
19
19
9
19
20
7
11
18
19
8
24
8
0
1
18
19
23
6
8
9
5
12
19
11
3
13
15
4
12
19
24
13
11
9
19
9
With the addition of this function bnbm will run every time you make an edit in A1 of sheet Dashboard.
function onEdit(e) {
//e.source.toast('entry');
const sh = e.range.getSheet();
if(sh.getName() == 'Dashboard' && e.range.rowStart == 1 && e.range.columnStart == 1 && e.value) {
bnbm();
}
if(sh.getName() == "Dashboard" && e.range.rowStart == 1 && e.range.columnStart == 1 && e.value == null) {
e.source.toast('Invalid Input','Error Message');
}
}
The easiest way I've found to run this is to enter data into A1 (user edits only) and then click on another cell. Hitting enter will not data just forces the focus back into the empty cell and does not complete the edit.

Related

Value Matching and reduce dimension in Java

I have a data file which consist of Marks of two subjects.
The file look like that
Sl_No: Marks1 Marks2
1 10 20
2 10 20
3 10 20
4 10 20
5 10 10
6 20 10
7 20 10
8 20 10
9 20 30
10 20 22
11 21 22
12 21 22
13 21 23
14 10 20
15 10 20
Now my objective is that whenever it get same pair of value add this marks. So as per my example sl_no 1 to 4 have same pairs of values (10,20). So it return 40 for Marks1 and 80 for marks2. Sl_No: 5 doesnot match with sl_no: 4 so it is remain same. Serial no: 6 to 8 have a matching pair so it return 60 and 30. Sl_no: 9.0 and 10.0 has no match so it remain same as it is. Sl_no: 11 and 12 had a match so return 42 and 44.and sl_no: 14 and 15 had a match so return 20 and 40.
Desired output:
4 40 80
5 10 10
8 60 30
9 20 30
10 20 22
12 42 44
13 21 23
15 20 40
My Code:
public class Marksmatch {
public static void main(String args[]){
int []sl_no={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int []Marks1={10,10,10,10,10,20,20,20,20,20,21,21,21,10,10};
int []Marks2={20,20,20,20,10,10,10,10,30,22,22,22,23,20,20};
int addMarks1=0,addMarks2=0;
for(int i=0;i<sl_no.length-1;i++){
if(Marks1[i]== Marks1[i+1]&&Marks2[i]==Marks2[i+1]){
addMarks1=addMarks1+Marks1[i+1];
addMarks2=addMarks2+Marks2[i+1];
System.out.println(addMarks1);
System.out.println(addMarks2);
}
}
}
}
Output:
10
20
20
40
30
60
50
70
70
80
91
102
101
122
It did not give me the desire output. How could I proceed?
Your logic is wrong. You should keep track of the sums of the current group, and only print them once you are done with the group:
int addMarks1=Marks1[0],addMarks2=Marks2[0]; // initialize the sums of the first group
for(int i=0;i<sl_no.length-1;i++){
if(Marks1[i]== Marks1[i+1] && Marks2[i]==Marks2[i+1]) {
// add to the current group
addMarks1=addMarks1+Marks1[i+1];
addMarks2=addMarks2+Marks2[i+1];
} else {
// print the previous group and start a new group
System.out.println(sl_no[i] + " " + addMarks1 + " " + addMarks2);
addMarks1=Marks1[i+1];
addMarks2=Marks2[i+1];
}
}
// print the last group
System.out.println(sl_no[sl_no.length-1] + " " + addMarks1 + " " + addMarks2)
Output:
4 40 80
5 10 10
8 60 30
9 20 30
10 20 22
12 42 44
13 21 23
15 20 40

Array Shuffle (With same Start and end Value)

I'm currently working on a Travelling salesman problem and i'm having trouble generating random paths with the same start and end value
This is my current path(path of cities visited)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 38 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 14 39 40 41 42 43 44 45 46 47 48 49 50 51 0
See how the last node arrives back at 0(TSP logic)
Now i'm trying to shuffle this array randomly because random start points generate better results then others However I know how to shuffle the array using Collections but that would shuffle every value randomly
Basically i'm trying to create a method to shuffle an array randomly WITH THE EXCEPTION THE START and END VALUES must be the same and every number must be distinct 0-51
This is my current code, it basically shuffles the array and sets the last index to the first index
static void shuffleArray(int[] ar)
{
// If running on Java 6 or older, use `new Random()` on RHS here
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
ar[ar.length-1]=ar[0];
}
however this is giving me duplicate values for some reason
Could you not remove the start and end position, shuffle the array, and then add the start and end position again?

How to split multiple tab delimited lines in Java if they all have a different number of columns?

I have a text file which is tab delimited, but there are a different number of columns on each line. Here is an example:
1 : 2 16 17 24 31 34 40 41 45 47 48
2 : 1 3 4 5 6 7 8 13 18 20 22 28 33 35 37 38 42 44 46 49
3 : 2 10 12 16 17 19 24 25 29 31 34 40 41 45
I want to use the split function, like I did here for a different assignment:
String[] words = line.split("\t");
col1 = Integer.parseInt(words[0]);
col2 = Integer.parseInt(words[1]);
col3 = Integer.parseInt(words[2]);
col4 = Integer.parseInt(words[3]);
This puts each column from a line into a different variable. I want to do the same but I'm not sure how to do this with a varying number of columns.
As said in the comments, you're quite good with what you've done. If you really want to have your Integer values stored somehow, you could simply use an Integer array, and fill it with a loop like this:
String[] words = line.split("\t");
int[] numbers = new int[words.length];
for (int i = 0; i < words.length; i++)
{
numbers[i] = Integer.parseInt(words[i]);
}
That whole thing being inside the loop you use to iterate your lines.
I don't think you need anything more complex than an array.

How to define a starting point in the condition?

The problem:
I want all numbers from 1-50 that are not divisible by 7, but also don't have a 7 in them, like 17,27,etc. The code below works but (i-10)%7 has to start from i=6. Now it thinks the number 3 doesn't count cause (3-10)=-7 that is 0 mod 7. how do i solve this in the if statement?
for(int i=1; i<=50;i++){
if(i%7!=0 && (i-10)%7!=0){
System.out.println(i);
Your second condition is wrong. 27 ends in 7, but (27-10)%7!=0.
You just need to check that i % 10 is not 7.
if(i%7!=0 && i%10!=7)
This will do the trick
for(int i=1; i<=50;i++){
if(i==7 || i==3)
{
if(i==3)
System.out.println(i);
}
else if(i%7!=0 && (i%10)%7!=0){
System.out.println(i);}
}
output is...
1 2 3 4 5 6 8 9 11 12 13 15 16 18 19 22 23 24 25 26 29 31 32 33 34 36 38 39 41 43 44 45 46 48
UPDATE
If you want your if condition to start checking from i=6 then you can do this...
for(int i=1; i<=50;i++){
if(i>=6 && i%7!=0 && (i%10)%7!=0)
System.out.println(i);
}
but the output will change to...
6 8 9 11 12 13 15 16 18 19 22 23 24 25 26 29 31 32 33 34 36 38 39 41 43 44 45 46 48
This should work. Casting it to a string and just checking if it contains the string "7".
if(i % 7 != 0 && ((String)i).contains("7"))
Its seems to basic:
find if the number has 7 or not : number%10==7
find if the number is divisible by 7 or not : number%7==0
combine both in Or clause
if (number%10==7||number%7==0)
do watever.......
but it only applicable if the number<50
If you're checking if each number contains a 7 instead of '(i-10)%7!=0' I would recommend casting i to a string (i + "") and then checking if it contains the char 7
using only i%10 !=7 will only check to see if the last digit is not 7.

Got wrong output in my task, cant solve it

Hello i got one task to do. output should be like this:
{
0
0 1
0 2 4
0 3 6 9
0 4 8 12 16
0 5 10 15 20 25
0 6 12 18 24 30 36
0 7 14 21 28 35 42 49
0 8 16 24 32 40 48 56 64
0 9 18 27 36 45 54 63 72 81
}
I tried to do it: here is my code:
public class ContnueUzOznakoMojNacin
{
public static void main(String args[])
{
int k=0, v=0;
int j;
for(int i=0;i<10;i++)
{
for(j=10-i;j<10;j++)
{
System.out.print(v+" ");
v+=k;
}
System.out.println();
v=0;
k++;
}
}
}
And the output i get is wrong and i dont get it why.
here it is:
{
0
0 2
0 3 6
0 4 8 12
0 5 10 15 20
0 6 12 18 24 30
0 7 14 21 28 35 42
0 8 16 24 32 40 48 56
0 9 18 27 36 45 54 63 72
}
When i follow these loops and increments from my program i cant find mistake.
first line is ok output should be 0;
but second line, output should be 0 1; not 0 2 ?
I dont need you to give me code for this task i need you to help me to do it, to tell me where i made mistake so i do it on my own. Thanks :)
Change this line:
for(j=10-i;j<10;j++)
to this:
for(j=9-i;j<10;j++)
And here's an explanation:
So i starts at 0, right? What will be i's maximum? 9, because in for(int i=0;i<10;i++), i cannot get to 10.
Let's look at how that affects for(j=10-i;j<10;j++). If i is 9 (the last row), then the j loop will only run 9 times. j will equal 1,2,3,4,5,6,7,8,9. That's only 9 loops. If you look at the bottom of the upper triangle, you can see that 0 9 18 27 36 45 54 63 72 has only 9 numbers.
We want j to run 10 times, as you can see by the base of the correct triangle: 0 9 18 27 36 45 54 63 72 81. How do we do this? We make j run one more time on every i loop, by decreasing the starting number (10-i) by one (which equals 9-i). That is how you arrive at
for(j=9-i;j<10;j++)

Categories