首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UnhandledPromiseRejectionWarning:错误:无效地址:未定义。怎么处理?

UnhandledPromiseRejectionWarning:错误:无效地址:未定义。怎么处理?
EN

Stack Overflow用户
提问于 2018-12-12 11:40:49
回答 1查看 1.9K关注 0票数 8

我正在遍历一个Excel文件的Sheet 1,该文件包含3个列,其中包含1000行数据(字符串),并将一行中的每个单元格与Sheet 2中的组合行进行比较。

检查应开始逐行使用Sheet 1,查看行中每个单元格的值是否与Sheet 2中的任何位置匹配。如果检查失败,则应停止对该行的进一步检查,并开始检查下一行。Sheet 1中无法匹配的细胞应标记为红色。

下面的代码接近我所需要的,但是如果Sheet 1的一行(例如Row 1: B2 and B3)中有两个或多个单元格与任何行Sheet 2中的任何单元格不匹配,则会抛出一个错误。

错误:

代码语言:javascript
复制
(node:9040) UnhandledPromiseRejectionWarning: Error: Invalid Address: Aundefined
    at Object.validateAddress (C:\node_modules\exceljs\dist\es5\utils\col-cache.js:86:13)
    at new module.exports (C:\node_modules\exceljs\dist\es5\doc\cell.js:29:12)
    at module.exports.getCellEx (C:\node_modules\exceljs\dist\es5\doc\row.js:55:14)
    at module.exports.getCell (C:\node_modules\exceljs\dist\es5\doc\row.js:72:41)
    at C:\so.js:56:61
    at C:\node_modules\exceljs\dist\es5\doc\worksheet.js:370:11
    at Array.forEach (<anonymous>)
    at module.exports.eachRow (C:\node_modules\exceljs\dist\es5\doc\worksheet.js:368:18)
    at C:\so.js:16:19
    at <anonymous>
(node:9040) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:9040) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

示例数据:

单张1:

代码语言:javascript
复制
| COL A | COL B  | COL C  |
|-------|--------|--------|
| bob   | one    | silver |
| bob   | eleven | blue   |
| bob   | eleven | red    |
| bob   | eleven | red    |
| bob   | one    | red    |
| bob   | eight  | red    |
| bob   | eight  | red    |
| bob   | eight  | red    |
| terry | seven  | yellow |
| terry | seven  | yellow |
| terry | seven  | gold   |

单张2:

代码语言:javascript
复制
| COL A | COL B  | COL C  |
|-------|--------|--------|
| bob   | eleven | blue   |
| bob   | eleven | red    |
| bob   | eight  | red    |
| terry | seven  | yellow |
| terry | seven  | orange |

根据示例数据,应该有三个单元格(B1B5C11)在Sheet 1 of new.xlsx中标记为红色。例如。

这是检查应该如何进行的scenarios example PDF

代码:

代码语言:javascript
复制
// Import the library
var Excel = require('exceljs'),
    moment = require('moment'),
    // Define Excel filename
    ExcelFile = 'so.xlsx',
    // Read from the file
    workbook = new Excel.Workbook();

workbook.xlsx.readFile(ExcelFile)
    .then(function()
    {
        // Use workbook
        var dataSheet = workbook.getWorksheet('Sheet 1'),
            masterSheet = workbook.getWorksheet('Sheet 2');

        dataSheet.eachRow({ includeEmpty: false }, function(dataRow, dataRowNumber)
        {
            var dataRowCells =
                {
                    dataCell1: dataRow.getCell('A'),
                    dataCell2: dataRow.getCell('B'),
                    dataCell3: dataRow.getCell('C')
                },
                isdataRowOK = false,
                oneOfBestMasterRowNumber,
                cellNames = ['A','B','C'];

            masterSheet.eachRow({ includeEmpty: false }, function(masterRow, masterRowNumber)
            {
                if(!isdataRowOK)
                {
                    var numberOfGoodCellsInRow = 0;

                    for(var i = 1; i < 4; i++)
                        if(dataRowCells['dataCell' + i].value === masterRow.getCell(cellNames[i-1]).value)
                            numberOfGoodCellsInRow++;

                    if(numberOfGoodCellsInRow == 2)
                        oneOfBestMasterRowNumber = masterRowNumber;

                    if(numberOfGoodCellsInRow == 3)
                        isdataRowOK = true
                }
            });


            if(!isdataRowOK)
            {
                var masterRowForCheck = masterSheet.getRow(oneOfBestMasterRowNumber);

                for(var i = 1; i < 4; i++)
                {
                    var dataCell = dataRowCells['dataCell' + i];
                    if(dataCell.value !== masterRowForCheck.getCell(cellNames[i-1]).value)
                    {
                        // Mark this failed cell as color red
                        dataCell.style = Object.create(dataCell.style); // Shallow-clone the style, break references
                        dataCell.fill = {type: 'pattern', pattern:'solid', fgColor:{argb:'FA8072'}}; // Set background
                    }
                }

            }
        });

        return workbook.xlsx.writeFile('new.xlsx');
    });
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-17 12:01:10

此错误的来源是来自行的第二个调用:

代码语言:javascript
复制
if(!isdataRowOK)

在这个位置上,变量oneOfBestMasterRowNumber不应该是undefined,如果行中的3个单元格是坏的,因为在它之后,如果getRow('undefined'),那么我们有一个错误。因此,我们现在检查它,如下所示,并为它编写值1 (1行号),因为在本例中它并不重要。

代码语言:javascript
复制
if(oneOfBestMasterRowNumber == void 0) //void 0 - undefined
    oneOfBestMasterRowNumber = 1;

还有一个地方我们应该改变:而不是代码行:

代码语言:javascript
复制
if(numberOfGoodCellsInRow == 2)
    oneOfBestMasterRowNumber = masterRowNumber;

我们应该写几句话:

代码语言:javascript
复制
if(numberOfGoodCellsInRow > numberOfGoodCellsInBestRow)
{
    numberOfGoodCellsInBestRow = numberOfGoodCellsInRow;
    oneOfBestMasterRowNumber = masterRowNumber;
}

因为行中不仅有一个单元格可能是坏的。我们现在也有了新的变量numberOfGoodCellsInBestRow

我认为如果行中的两个或三个单元格是坏的,最好是标记它们,但是如果您希望行中只有一个单元格,那么您可以在单元格着色后取消注释break;

还请参阅我在下面代码中的评论:

代码语言:javascript
复制
// Import the library
var Excel = require('exceljs'),
    moment = require('moment'),
    // Define Excel filename
    ExcelFile = 'so.xlsx',
    // Read from the file
    workbook = new Excel.Workbook();

workbook.xlsx.readFile(ExcelFile)
    .then(function()
    {
        // Use workbook
        var dataSheet = workbook.getWorksheet('Sheet 1'),
            masterSheet = workbook.getWorksheet('Sheet 2');

        dataSheet.eachRow({ includeEmpty: false }, function(dataRow, dataRowNumber)
        {
            var dataRowCells =
                {
                    dataCell1: dataRow.getCell('A'),
                    dataCell2: dataRow.getCell('B'),
                    dataCell3: dataRow.getCell('C')
                },
                isdataRowOK = false,
                oneOfBestMasterRowNumber,
                cellNames = ['A','B','C'],
                numberOfGoodCellsInBestRow = 0;

            masterSheet.eachRow({ includeEmpty: false }, function(masterRow, masterRowNumber)
            {
                if(!isdataRowOK)
                {
                    var numberOfGoodCellsInRow = 0;

                    for(var i = 1; i < 4; i++)
                        if(dataRowCells['dataCell' + i].value === masterRow.getCell(cellNames[i-1]).value)
                            numberOfGoodCellsInRow++;

                    //here we detect if 1 or 2 cells are bad
                    if(numberOfGoodCellsInRow > numberOfGoodCellsInBestRow)
                    {
                        numberOfGoodCellsInBestRow = numberOfGoodCellsInRow;
                        oneOfBestMasterRowNumber = masterRowNumber;
                    }

                    if(numberOfGoodCellsInRow == 3)
                        isdataRowOK = true
                }
            });

            //here was error source: oneOfBestMasterRowNumber
            //should be not undefined if 3 cells in row are bad
            if(oneOfBestMasterRowNumber == void 0)//void 0 - undefined
                oneOfBestMasterRowNumber = 1;

            if(!isdataRowOK)
            {
                //here was error place: if getRow('undefined') then was error
                var masterRowForCheck = masterSheet.getRow(oneOfBestMasterRowNumber);

                for(var i = 1; i < 4; i++)
                {
                    var dataCell = dataRowCells['dataCell' + i];
                    if(dataCell.value !== masterRowForCheck.getCell(cellNames[i-1]).value)
                    {
                        // Mark this failed cell as color red
                        dataCell.style = Object.create(dataCell.style); // Shallow-clone the style, break references
                        dataCell.fill = {type: 'pattern', pattern:'solid', fgColor:{argb:'FA8072'}}; // Set background
                        //break; uncomment this if you want only one cell as color red marked in the row
                    }
                }

            }
        });

        return workbook.xlsx.writeFile('new.xlsx');
    });
}

示例可视化

我已经将Node.js代码翻译成客户端JavaScrpt代码,通过检查下面的片段中的两个不同的数据集(模拟Excel表)来演示它。

代码语言:javascript
复制
function checkDataset(obj)
{
    var radios = obj.parentNode.elements['dataset'],
        dataSetNumber,
        i = radios.length;

    for(; i--;)
        if(radios[i].checked)
        {
            dataSetNumber = i;
            break
        }

    var dataSheet = xlsFile['data' + dataSetNumber],
        masterSheet = xlsFile['master' + dataSetNumber];

    dataSheet.forEach(function(dataRow, dataRowIndex)
    {
        var dataRowCells =
            {
                dataCell1: dataRow.A,
                dataCell2: dataRow.B,
                dataCell3: dataRow.C
            },
            isdataRowOK = false,
            oneOfBestMasterRowIndex,
            cellNames = ['A','B','C'],
            numberOfGoodCellsInBestRow = 0;

        masterSheet.forEach(function(masterRow, masterRowIndex)
        {
            if(!isdataRowOK)
            {
                var numberOfGoodCellsInRow = 0;

                for(var i = 1; i < 4; i++)
                    if(dataRowCells['dataCell' + i].value === masterRow[cellNames[i-1]].value)
                        numberOfGoodCellsInRow++;

                //here we detect if 1 or 2 cells are bad
                if(numberOfGoodCellsInRow > numberOfGoodCellsInBestRow)
                {
                    numberOfGoodCellsInBestRow = numberOfGoodCellsInRow;
                    oneOfBestMasterRowIndex = masterRowIndex;
                }

                if(numberOfGoodCellsInRow == 3)
                    isdataRowOK = true
            }
        });

        //oneOfBestMasterRowIndex should be not undefined if 3 cells in row are bad
        if(oneOfBestMasterRowIndex == void 0)//void 0 - undefined
            oneOfBestMasterRowIndex = 0;

        if(!isdataRowOK)
        {
            var masterRowForCheck = masterSheet[oneOfBestMasterRowIndex];

            for(var i = 1; i < 4; i++)
            {
                var dataCell = dataRowCells['dataCell' + i];
                if(dataCell.value !== masterRowForCheck[cellNames[i-1]].value)
                {
                    // Mark this failed cell as color red
                    dataCell.bgColor = 'red';
                    //break; uncomment this if you want only one cell as color red marked in the row
                }
            }

        }
    });

    var table = '<table border="1"><tr style="background:#00a;color:#fff">'
                + '<th>A</th><th>B</th><th>C</th></tr>';

    dataSheet.forEach(function(dataRow, dataRowIndex)
    {
        table += '<tr>';
        for(var i in dataRow)
            table += '<td bgcolor="' + (dataRow[i].bgColor ? 'red' : '')
                        + '">' + dataRow[i].value + '</td>';

        table += '</tr>';
    });
    document.write(table + '</table>');
}

function cells(strValues)
{
    var v = strValues.split('\t');
    return{A: {value: v[0]}, B: {value: v[1]}, C: {value: v[2]}}
}

var xlsFile =
{
    //Dataset 1:
    data0:
    [
        cells('bob	sacsac	sxcsc'),
        cells('sacfbrb	eleven	blue'),
        cells('ascasc	one	red'),
        cells('tyjytn	one	red'),
        cells('ascsac	one	red'),
        cells('terry	elf	yellow'),
        cells('terry	seven	elf'),
        cells('terry	elf	elf'),
        cells('terry	elf	elf'),
        cells('terry	seven	yellow'),
        cells('terry	elf	elf'),
        cells('terry	seven	orange'),
        cells('terry	seven	yellow'),
        cells('santa	mary	jane'),
        cells('bob	zero	mauve'),
        cells('bob	one	silver'),
        cells('bob	eleven	blue'),
        cells('bob	eleven	red'),
        cells('bob	eleven	red'),
        cells('bob	one	red'),
        cells('bob	eight	red'),
        cells('bob	eight	red'),
        cells('bob	eight	red'),
        cells('terry	seven	yellow'),
        cells('terry	seven	yellow'),
        cells('terry	seven	gold')
    ],
    master0:
    [
        cells('bob	eleven	blue'),
        cells('bob	eleven	red'),
        cells('bob	eight	red'),
        cells('terry	seven	yellow'),
        cells('bob	seven	yellow'),
        cells('terry	seven	orange'),
        cells('tiger	one	red')
    ],


    //Dataset 2:
    data1:
    [
        cells('bob	one	blue'),
        cells('bob	eleven	blue'),
        cells('bob	eleven	red'),
        cells('bob	eleven	red'),
        cells('bob	one	red'),
        cells('bob	eight	red'),
        cells('bob	eight	red'),
        cells('bob	eight	red'),
        cells('terry	seven	yellow'),
        cells('terry	seven	yellow'),
        cells('terry	seven	gold')
    ],
    master1:
    [
        cells('bob	eleven	blue'),
        cells('bob	eleven	red'),
        cells('bob	eight	red'),
        cells('terry	seven	yellow'),
        cells('terry	seven	orange')
    ]
};
代码语言:javascript
复制
<form method="post" action="#">
    <p><b>Which dataset do you want check?</b></p>
    <label><input type="radio" name="dataset">Dataset 1</label><br>
    <label><input type="radio" name="dataset" checked>Dataset 2</label><br><br>
    <input type="button" value="Check it" onclick="checkDataset(this)">
</form>

祝圣诞快乐,新年愉快!

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53742262

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档