Cannot convert error when assigning array to a range - arrays

Below is my code and on the last line of code I get a "Cannot convert error". To clarify the line: sheet.getRange throws the error.
That is all the error says; nothing more, just "Cannot convert". Also, this is the full code, so there is nothing else.
function days(){
var table = new Array(7);
for ( var i = 0; i < 7 ; i ++){
table[i] = i+2;
}
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Want");
sheet.getRange("B2:B9").setValues(table);
}

I don't know anything about Google Apps Scripting, but I managed to find this on Google.
It appears your table needs to be a 2-dimensional array.
Perhaps this can help?
(code is from the link above)
var myTable = [[1, 2, 3, 4],[5, 6, 7, 8]];
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(1,1,2,4).setValues(myTable);

SetValues() takes a 2 dimensions array as argument, TABLE is a 1 dimension array... this cannot work as it is... It's easy to change though, make table a 2D array of 7 elements.
like this : table[i] = [i+2];
btw, range ('B2:B9') is 8 cells high and you only give 7 values... there will be a problem there !

I figured out the problem to this question, so I will answer the question so that others may benefit. The problem here is that the .setValues method for a Range object must be given a two dimensional array [][]. So I created a 0 dimensional array inside of the other one so that i now had a two dimensional array.
var array = new Array(7);
for (var i = 0; i < 7; i++) {
array[i] = new Array(0);
}

Related

Search and replace string in 2D Array in Swift

Teaching myself swift, so complete noob here, but I'm far into a project and just know there must be an easier way to achieve something.
I have a 2D array:
var shopArray = [
["theme":"default","price":0,"owned":true,"active":true,"image":UIImage(named: "defaultImage")!,"title":"BUY NOW"],
["theme":"red","price":1000,"owned":false,"active":false,"image":UIImage(named: "redImage")!,"title":"BUY NOW"],
["theme":"blue","price":2000,"owned":false,"active":false,"image":UIImage(named: "blueImage")!,"title":"BUY NOW"],
["theme":"pool","price":3000,"owned":true,"active":false,"image":UIImage(named: "blueImage")!,"title":"BUY NOW"],
["theme":"line","price":4000,"owned":false,"active":false,"image":UIImage(named: "lineImage")!,"title":"BUY NOW"],
["theme":"neon","price":5000,"owned":false,"active":false,"image":UIImage(named: "lineImage")!,"title":"BUY NOW"]]
Where I simply want to create a function that runs and search for all the "owned" keys and make them all "false".
How do you search and replace in Arrays / 2D Arrays. More specifiaclly, what should the func look like?
Thank you!
You don't have a 2D array, you have an Array of Dictionaries.
You can set all of the values for the owned keys by iterating the indices of the Array and updating the values:
shopArray.indices.forEach { shopArray[$0]["owned"] = false }
That is the functional way to do it. You could also do the same operation with a for loop:
for idx in shopArray.indices {
shopArray[idx]["owned"] = false
}
You could do something like this to loopthrough the array replacing the approriate element.
var i = 0
for x in shopArray {
var y = x
y["owned"] = false
shopArray.remove(at: i)
shopArray.insert(y, at: i)
i = i + 1
}
or you could use a while loop to do the same with less code lines.
var y = 0
while y < shopArray.count {
shopArray[y].updateValue(false, forKey: "owned")
y += 1
}
There is proably somthing doable with .contains, but I'm not sure you need that toachive the result you mention above. Play around in a play ground in xcode and try a few different options without doing anything that might cause issues in your project.

finding a str in MatLab cells

I am currently using MatLab R2014a
I have one array and one cell:
MyArray = ['AA1', 'AA2', 'AB1', 'AB2', 'Acc1', 'Acc2'];
MyCell = {'Name1AA1', 'Name2AA1', 'Name3Acc2', 'Name4AB2', 'Name5AD1};
MyArray consists of code names that are repeatable throughout MyCell.
I would like to check if any of the strings in MyArray are in MyCell and if it is, save the name to a new cell.
For now I have:
NewCell = {};
for i = 1:length(MyCell)
for j = 1:length(MyArray)
Find = strfind(MyCell(i), MyArray)
if ~isempty(Find)
NewCell = {NewCell; MyCell(j)}
end
end
end
However, when I use strfind I get this error message:
Undefined function 'strfind' for input arguments of type 'char'
If I use strcmp instead of strfind, I get an array of everything in MyCell repeated by the number of elements in MyArray.
My Ideal output would be:
NewCell1 = {'Name1AA1', 'Name2AA1'}
NewCell2 = {'Name4AB2'}
NewCell3 = {'Name3Acc2'}
ie, no new cell for the code names that are not present in MyArray or no new cell if there is a code name in MyArray but not in MyCell.
Any help is welcome, and thanks for your time
You can use a combination of regular expressions to achieve the desired output. Your approach of wanting to name variables dynamically is not recommended and will lead to code which is harder to debug. Use indexing instead.
You can read this informative post on Matlab's forum to understand why.
%Your input data.
MyArray = ['AA1', 'AA2', 'AB1', 'AB2', 'Acc1', 'Acc2'];
MyCell = {'Name1AA1', 'Name2AA1', 'Name3Acc2', 'Name4AB2', 'Name5AD1'};
%Find common elements between MyArray and MyCell.
elem = cellfun(#(x) regexp(MyArray,x(end-2:end),'match'),MyCell,'un',0);
%Eliminate duplicates.
NewCell = unique([elem{:}]);
%Find elements in MyCell which end with NewCell elements and group them.
NewCell = cellfun(#(x) regexp([MyCell{:}],strcat('Name\d\w?',x),'match'),NewCell,'un',0);
%Join elements.
NewCell{1} = {strjoin(NewCell{1},''',''')};
NewCell{1} = {'Name1AA1','Name2AA1'}
NewCell{2} = {'Name4AB2'}
NewCell{3} = {'Name3Acc2'}

Google App Script Array - Why Return Undefined?

I have written something like this on Google App Script:
var crossup = [];
var i;
var name_cell;
var cross_up_cell;
cross_up_cell = sheet.getRange(2, 1);
for (i = 1; i <= 12; i++) {
var ticker;
var value1;
ticker = name_cell.offset(0, i).getDisplayValue();
value1 = cross_up_cell.offset(0, i).getDisplayValue();
if (value1=="YES") {crossup.push(ticker)};
}
What I had in mind: I thought I was going to output an array of value1 with the value "ticker" assign by getDisplayValue(), but as I output the array, it turns out that I received a series of "undefined" as output.
To be exact, whenever value1 is really "YES" on my Google SpreadSheet, the if statement did "push" "ticker" into the crossup array, but instead of pushing back the display value, it pushed back "undefined"...
Help!!! How come?
The var name_cell isn't set.
Use code below, where
cross_up_cell = sheet.getRange(2, 1);
sheet = SpreadsheetApp.getActiveSheet();
cross_up_cell = sheet.getRange(2, 1);
You never fully define name_cell, so your offset method for ticker returns an undefined cell/range, which then gets pushed to your crossup array.
Your syntax is a bit odd with initializing and assigning variables, so I've rewritten the snippet you posted:
function myFunction() {
var sheet = SpreadsheetApp.openById(*****).getSheetByName("PASTEVALUE"), //get sheet
crossup = []; //initialize empty crossup array
//get the display values in row 2 up to column 12
var values = sheet.getRange(2, 1, 1, 12).getDisplayValues()[0];
//get the display values in row 3 up to column 12, assuming they are in row 3
var ticker = sheet.getRange(3, 1, 1, 12).getDisplayValues()[0];
//initialize increment in for loop, i's value goes from 0 to values.length-1 (the array's full index range)
for (var i in values) {
//if the value in row 2, column "i" is "YES", push the value of row 3, column "i" to the crossup Array
if (values[i] == "YES") crossup.push(ticker[i]);
}
//do stuff with crossup...
}
Instead of incrementally offsetting cells, you can use getDisplayValues() of an extended Range (full row or column, or multiple rows and columns) to get a 2D array, which I think is much quicker to increment through.
Either defining name_cell in your example or editing to make the syntax changes should fix your problem. Let me know if you have any problems or questions.

How to append array data to spreadsheet column at once using Google Script?

I am trying to append data of addArray[] to end of column A at once. However, my array is not multidimensional to be able to use this method:
this is how i add to array:
var toAdd=[];
var thisurl="red apple http://awebsite.com/1.jpg";
toAdd.push(thisUrl);
And this is the way i would like to append the array at once
function AddToSpreadsheet()
{
var data = SpreadsheetApp.getActiveSheet().getRange('A12:A').getValues();
var toAdd=["red apple http://awebsite.com/1.jpg",
"green apple http://1awebsite.com/2.jpg",
"red apple http://1awebsite.com/3.jpg",
"rotten apple http://rottenApple.com"];
if(toAdd.length > 0){
for(i = 0; i < data.length; ++i){
if(data[i][0] == ""){break;}
}
SpreadsheetApp.getActiveSheet().getRange(12+i, 1, toAdd.length, 1).setValues(toAdd);
}
}
if i use this above code i get this error:
Cannot convert Array to Object[][]. (line
My addArray is not multidimensional array ! How i can convert it to multidimensional array like the following example so i can use the above code ?
Multidimensional array example :
var toAdd=[["red apple http://awebsite.com/1.jpg"],
["green apple http://1awebsite.com/2.jpg"],
["red apple http://1awebsite.com/3.jpg"],
["rotten apple http://rottenApple.com"]];
Edit: I converted the array at start and worked!
var values_array=["red apple http://awebsite.com/1.jpg",
"green apple http://1awebsite.com/2.jpg",
"red apple http://1awebsite.com/3.jpg",
"rotten apple http://rottenApple.com"];
var toAddArray = [];
for (i = 0; i < toAdd.length; ++i){
toAddArray.push([toAdd[i]]);
}
...........
and this way i inserted the whole new array to column A:
............
SpreadsheetApp.getActiveSheet().getRange(12+i, 1, toAddArray.length, 1).setValues(toAddArray);
}
You need to "transpose" the array.
You can do that by creating a new array and appending the values as arrays with one value.
before you call setValues(toAdd) try
var toAddArray = [];
for (i = 0; i < toAdd.length; ++i){
toAddArray.push([toAdd[i]]);
}
And replace the set values call with
SpreadsheetApp.getActiveSheet().getRange(12+i, 1, toAdd.length, 1).setValues(toAddArray);
The set values function needs a matrix as an input. Since there is no native matrix it requires an array of arrays where each of the subarrays have the same length and contain no arrays.
Each array within the "matrix" is a row and each element of each arrays goes into a column.
If you want one column of rows from a one dimensional array you need an array with one-element arrays. If you want to write columns you make an array containing one array of all values.
The items you receive from the sheet are immutable and that's why you can't append to them, however you can copy the values into a new array and overwrite the old one. I however, would have taken another approach to this issue and just printed to the end of the column like this:
function appendToSheet() {
var sheet = SpreadsheetApp.getActive().getSheetByName('test'); // Get sheet so I don't have to retype it every time
var toAppend = [['Append 1'],['Append 2']]; // Note that this is an array of arrays.
var newRow = sheet.getLastRow() + 1; // This fetches the number of the last row of the entire sheet and adds one to it.
var endRange = lastRow + toAppend.length - 1; // Calculate the last row to append to
sheet.getRange('A' + newRow + ':A' + endRange).setValues(toAppend); // Write to sheet.
}
But if you want to use the sheet array and the appended data in your code elsewhere I'd do like this where I dynamically calculate the range I need and only fetch that, instead of fetching the entire sheet and work with that:
function appendToValues() {
var sheet = SpreadsheetApp.getActive().getSheetByName('test');
var lastRow = sheet.getLastRow();
var valuesFromSheet = sheet.getRange('A1:A' + lastRow).getValues(); // Get values from the sheet
var toAppend = [['value 1'],['value 2']];
var newArray = valuesFromSheet.concat(toAppend); // .concat() copies the old immutable array and makes a new one with the append array included.
}

Find Specific Array Using a Loop

I'm incredibly new to swift and I'm sure this question has been asked before, but I have no idea of the terminology of what to search.
I've seen how to do this before, but not sure where. I want to be able to loop though my arrays using a count, like the below (but that is not working). So the last number of the array name changes depending on the count. So if myCount = 0 then myArray will equal array_0001_00 and if my count = 6 then myArray will equal array_0001_06, and so on.
I'm not sure if I'm missing something small or if I'm completely on the wrong track.
let array_0001_00 = [102,102,102,102,102,102,102,102]
let array_0001_01 = [112,112,112,112,112,112,112,112]
myArray = array_0001_0\(myCount)
Any help would be much appreciated. Thanks.
I'm currently using the below, which works, but is creating a mountain of code:
if myCount == 0 {
myArray = array_0001_00
} else if myBuilderCountY == 1 {
myArray = array_0001_01
}
I hope I haven't misunderstood - you have a number of arrays, and you want to select one of them using an index. That looks like selecting an element from an array:
let array_0001_00 = [102,102,102,102,102,102,102,102]
let array_0001_01 = [112,112,112,112,112,112,112,112]
let array_0001_02 = [122,122,122,122,122,122,122,122]
let array_of_arrays = [
array_0001_00,
array_0001_01,
array_0001_02
]
let index = 1
let myArray = array_of_arrays[index] // This assigns (a copy of) array_0001_01

Resources