导入CSV数据时,范围宽度不正确

时间:2016-01-05 08:54:40

标签: google-apps-script google-sheets google-apps csv-import

我正在使用Google Apps脚本导入CSV数据。导入了所有CSV数据,但仍会显示此错误消息:

  

范围宽度不正确,为1,但应为5

我的CSV文件使用';'分隔,并且其中也有逗号。我的CSV文件示例:

FJ32-19A354-AA;'BES_301 - Exterior Trim;'000101;BOM No CAD;04/01/16

总共有5列,当我在getRange()调用中说明列数时,我收到另一个错误:

  

找不到方法getRange(数字,数字,数字,数字,数字)

我目前正在使用的示例代码(改编自"Ask Ben"):

var ss = SpreadsheetApp.openById('1V8YG8lyNZiTllEPHENcnabYRLDPCK6mHGUyAyNhW0Is'); // data_sheet_id = id of spreadsheet that holds the data to be updated with new report data
var s = SpreadsheetApp.getActiveSheet();
var csv = file.getBlob().getDataAsString();
var csvData = CSVToArray(csv); // see below for CSVToArray function
var lastrow = s.getLastRow(); 
  s.getRange(lastrow+ 1, 1,5, csvData.length, csvData[0].length).setValues(csvData);

function CSVToArray( strData, strDelimiter ){

    strDelimiter = (strDelimiter || ";");


    var objPattern = new RegExp(
        (
            // Delimiters.
            "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +

            // Quoted fields.
            "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +

            // Standard fields.
            "([^\"\\" + strDelimiter + "\\r\\n]*))"
        ),
        "gi"
        );


    var arrData = [[]];

    var arrMatches = null;

    while (arrMatches = objPattern.exec( strData )){

        // Get the delimiter that was found.
        var strMatchedDelimiter = arrMatches[ 1 ];

        // Check to see if the given delimiter has a length
        // (is not the start of string) and if it matches
        // field delimiter. If id does not, then we know
        // that this delimiter is a row delimiter.
        if (
            strMatchedDelimiter.length &&
            strMatchedDelimiter !== strDelimiter
            ){

            // Since we have reached a new row of data,
            // add an empty row to our data array.
            arrData.push( [] );

        }

        var strMatchedValue;

        // Now that we have our delimiter out of the way,
        // let's check to see which kind of value we
        // captured (quoted or unquoted).
        if (arrMatches[ 2 ]){

            // We found a quoted value. When we capture
            // this value, unescape any double quotes.
            strMatchedValue = arrMatches[ 2 ].replace(
                new RegExp( "\"\"", "g" ),
                "\""
                );

        } else {

            // We found a non-quoted value.
            strMatchedValue = arrMatches[ 3 ];

        }

        // Now that we have our value string, let's add
        // it to the data array.
        arrData[ arrData.length - 1 ].push( strMatchedValue );
    }

    // Return the parsed data.
    return( arrData );
}

2 个答案:

答案 0 :(得分:2)

错误来自这行代码:

s.getRange(lastrow+ 1, 1,5, csvData.length, csvData[0].length).setValues(csvData);

括号内有5个值。 getRange()最多需要4个参数。

.getRange(start Row, start Column, Number of Rows, Number of Columns)

删除号码5csvData.length

目前,csvData.length可能用于“列数”设置,而不是csvData[0].length

当我使用您的示例数据运行CSVToArray()函数时,我得到一个二维数组:

[["FJ32-19A354-AA", "'BES_301 - Exterior Trim", "'000101", "BOM No CAD", "04/01/16"]]

当我记录长度时:

Logger.log('arrData[0].length: ' + arrData[0].length);

它返回5的正确长度。因此,对于您提供的数据示例,CSVToArray()函数看起来正常。

现在,5所在的地方有number of rows个数字。但是外部数组中只有一个内部数组。这将理解错误信息。代码“认为”应该有5行,但只有一行。

答案 1 :(得分:1)

导入CSV文件时,行长度会有所不同,这会导致此错误。 您需要确保所有行的大小相同

首先,您需要一个函数来调整行,从另一个stackoverflow主题复制:

function resize(array, newSize, defaultValue) {
    while(newSize > array.length)
        array.push(defaultValue);
    array.length = newSize;
}

然后你可以导入:

function readCSV(sheet, data) {

  var table = [];
  var lines = data.split("\n");
  var maxCol = 0;
  for (var l = 0; l < lines.length; ++l) {
    var line = lines[l];
    var cells = line.split(",");
    table.push(cells);

    if (maxCol < cells.length)
      maxCol = cells.length;
  }

  // Important!
  // resize all rows to be of the same column number, otherwise setValues will fail!
  for (var i = 0; i < table.length; ++i)
    resize(table[i], maxCol, '');


  sheet.getRange(1, 1, table.length, table[0].length).setValues(table);


  SpreadsheetApp.flush();
}