Из массива в setValues выдает: "Не удается преобразовать в."
ФОН. Я хочу изменить расписание из формата недели (в каждой строке указано 7 дней, ни одна дата не доступна, только неделя в yyww (например, 1225). На другом листе в одном столбце указывается неделя, а в другом - даты.
МЕТОД. Я беру эти два листа в два массива, упаковываю третий массив, значения которого я установил в третий лист.
ПРОБЛЕМА. В этой строке выдается сообщение об ошибке: "Не удается преобразовать в."
sheet_IndataTabell.getRange(1,1,IndataTable.length+1,7).setValues(IndataTable);
Источник. Вы можете увидеть документ здесь и полную функцию ниже:
function UpdateTable() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet_Indata = ss.getSheetByName("Indata");
var sheet_IndataTabell = ss.getSheetByName("Indata_Tabell");
var sheet_Calendar = ss.getSheetByName("Kalender");
//Get the table into arrays
var Indata = sheet_Indata.getDataRange();
var CalendarTable = sheet_Calendar.getDataRange();
//Gets the values in the Indata to an Array
var NumberRows = Indata.getLastRow();
var NumberCols = Indata.getLastColumn();
//Browser.msgBox(NumberRows + " " + NumberCols);
var IndataArray = new Array(NumberRows,NumberCols);
var IndataArray = Indata.getValues();
//Create an Array to store the result
var IndataTable = new Array(((NumberCols-1)*(NumberRows-1)),7);
//Browser.msgBox("First the IndataTable is defined as: (NumberCols-1)*(NumberRows-1) (" + (NumberCols-1)*(NumberRows-1) + ").");
//Gets the values in the Calendar to an Array
var NumberRows_Cal = CalendarTable.getLastRow();
var NumberCols_Cal = CalendarTable.getLastColumn();
//Browser.msgBox(NumberRows + " " + NumberCols);
var CalendarArray = new Array(NumberRows_Cal,NumberCols_Cal);
var CalendarArray = CalendarTable.getValues();
for (i=1; i<(IndataArray.length); i++)
{
for (j=3; j<10; j++) {
IndataTable[i*7+j-3-7] = {};
//adds the users
IndataTable[i*7+j-3-7][0] = IndataArray[i][1];
//adds the week numbers
var Vecka = IndataArray[i][2];
IndataTable[i*7+j-3-7][1] = Vecka;
//adds the hours
IndataTable[i*7+j-3-7][2] = IndataArray[i][j];
//adds the projects
IndataTable[i*7+j-3-7][3] = IndataArray[i][10];
//adds the day
var Dag = (j-2);
IndataTable[i*7+j-3-7][4] = Dag;
//Gets the date from the Calendar
IndataTable[i*7+j-3-7][5] = "=VLOOKUP(G" + (i*7+j-9) + ";Kalender!$B$1:C;2)+E" + (i*7+j-9) + "-1";
IndataTable[i*7+j-3-7][6] = Vecka+"_"+Dag;
//Browser.msgBox("[" + (i*7+j-3-7) + "][n]: " + IndataTable[i*7+j-3-7][0] + ", " + IndataTable[i*7+j-3-7][1] + ", " + IndataTable[i*7+j-3-7][2] + ", " + IndataTable[i*7+j-3-7][3] + ", " + IndataTable[i*7+j-3-7][4] + ", " + IndataTable[i*7+j-3-7][5] + ", " + IndataTable[i*7+j-3-7][6]);
}
}
sheet_IndataTabell.clear();
//Browser.msgBox("IndataTable.length: " + IndataTable.length);
//Browser.msgBox("IndataTable[0].length: " + IndataTable[0].length);
//Browser.msgBox("Last row on Range: " + sheet_IndataTabell.getRange(1, 1, IndataTable.length,7).getLastRow());
//Browser.msgBox(IndataTable);
sheet_IndataTabell.getRange("A1:G28").setValues(IndataTable);
//sheet_Indata.sort(3,true);
//Browser.msgBox("Uppdatering klar!");
sheet_IndataTabell.getRange("J1").setValue(Date());
}
1 ответ
setValues()
а также getValues()
всегда используйте 2 размерных массива, даже если диапазон составляет всего 1 строку, поэтому вы должны использовать:
LINE 212 sheet_IndataTabell.getRange(1, 1, 1, 2).setValues([IndataTable_Temp])
(обратите внимание на пару скобок, которые я добавил.)
Кроме того, даже если это не проблема, вам не нужно определять размер массива перед использованием Range.getValues()
брось (NumberRows_Cal,NumberCols_Cal)
вы указали в качестве параметров,
var CalendarArray = new Array()
достаточно.
РЕДАКТИРОВАТЬ: по поводу вашего комментария: пожалуйста, добавьте эти два файла Logger.log в свой код в строке 225, когда вы получите 2 массива, один из которых нельзя использовать в setValues (), и вы увидите, что произошло:
Logger.log(IndataTable);//this one contains JS objects between {}
Logger.log(IndataTable_Temp);// this one contains array elements between [[]]
//Writes the array content to the sheet
sheet_IndataTabell.getRange(1, 1, i, 11).setValues(IndataTable_Temp);
РЕДАКТИРОВАТЬ 2: Я внес небольшое изменение в конец вашего скрипта, теперь данные - это чистые строки, а массив - реальный 2D (посмотрите скобки снова):
//Reconstruction the Array, I do not know why this is needed
var IndataTable_Temp = new Array();
for (i=0; i<IndataTable.length; i++) {
// Logger.log(typeof(IndataTable[i][0]))
IndataTable_Temp.push([
IndataTable[i][0],
IndataTable[i][1],
IndataTable[i][2],
IndataTable[i][3],
IndataTable[i][4],
IndataTable[i][5],
IndataTable[i][6],
IndataTable[i][7],
IndataTable[i][8],
IndataTable[i][9],
IndataTable[i][10]
]);
}
Logger.log(IndataTable)
Logger.log(IndataTable_Temp)
//Writes the array content to the sheet
sheet_IndataTabell.getRange(1, 1, IndataTable_Temp.length, IndataTable_Temp[0].length).setValues(IndataTable_Temp);
//Sets timestamp
sheet_IndataTabell.getRange("L1").setValue(Date());
Хотя это старая ветка, мой ответ может помочь другим, ищущим здесь, решить эту проблему,
В основном эта функция просматривает массив и проверяет, есть ли пустой слот, затем берет значение из предыдущего слота и добавляет к нему текст.
function addText(){
var ss = SpreadsheetApp.getActiveSpreadsheet(); //Getting active spreadsheet
var s = ss.getActiveSheet(); //Getting active sheet
var sheetName = s.getSheetName(); //Getting active sheet name
var lastRow = s.getLastRow(); //Getting sheets last row number
if (sheetName == "sheetName") { //Checking if active sheet is that we want to be
var jobValuesRange = s.getRange("C8:C" + lastRow); //Getting range that is only one column
var jobValues = jobValuesRange.getValues(); //Getting values from only one column
for (var i = 0; i < jobValues.length + 1; i++) { //Looping through all array values
if (jobValues[i] == "") {
//Here is MAGIC where you must add brackets to create two dimension array.
//Array should be like with lot of rows like first dimension and second dimension,
//like one cell in that row.
jobValues[i] = [jobValues[i - 1] + " night"];
}
}
jobValuesRange.setValues(jobValues); // Here you are just updating old values to new values
}
}