diff --git a/calc.go b/calc.go index ba51590b3f..44dc4e44af 100644 --- a/calc.go +++ b/calc.go @@ -1690,16 +1690,31 @@ func (f *File) rangeResolver(ctx *calcContext, cellRefs, cellRanges *list.List) // extract value from ranges if cellRanges.Len() > 0 { arg.Type = ArgMatrix + + var ws *xlsxWorksheet + ws, err = f.workSheetReader(sheet) + if err != nil { + return + } + for row := valueRange[0]; row <= valueRange[1]; row++ { + colMax := 0 + if row <= len(ws.SheetData.Row) { + rowData := &ws.SheetData.Row[row-1] + colMax = min(valueRange[3], len(rowData.C)) + } + var matrixRow []formulaArg for col := valueRange[2]; col <= valueRange[3]; col++ { - var cell string - var value formulaArg - if cell, err = CoordinatesToCellName(col, row); err != nil { - return - } - if value, err = f.cellResolver(ctx, sheet, cell); err != nil { - return + value := newEmptyFormulaArg() + if col <= colMax { + var cell string + if cell, err = CoordinatesToCellName(col, row); err != nil { + return + } + if value, err = f.cellResolver(ctx, sheet, cell); err != nil { + return + } } matrixRow = append(matrixRow, value) } diff --git a/calc_test.go b/calc_test.go index 7581203d96..5f24cd3544 100644 --- a/calc_test.go +++ b/calc_test.go @@ -6303,6 +6303,43 @@ func TestCalcBetainvProbIterator(t *testing.T) { assert.Equal(t, 1.0, betainvProbIterator(1, 1, 1, 1, 1, 1, 1, 1, 1)) } +func TestCalcRangeResolver(t *testing.T) { + f := NewFile() + assert.NoError(t, f.SetCellFormula("Sheet1", "A1", "=SUM(Sheet1!B:B)")) + cellRefs := list.New() + cellRanges := list.New() + // Test extract value from ranges on invalid ranges + cellRanges.PushBack(cellRange{ + From: cellRef{Col: 1, Row: 1, Sheet: "SheetN"}, + To: cellRef{Col: 1, Row: TotalRows, Sheet: "SheetN"}, + }) + _, err := f.rangeResolver(&calcContext{}, cellRefs, cellRanges) + assert.EqualError(t, err, "sheet SheetN does not exist") + + ws, err := f.workSheetReader("Sheet1") + ws.SheetData.Row = make([]xlsxRow, TotalRows+1) + ws.SheetData.Row[TotalRows].C = make([]xlsxC, 3) + assert.NoError(t, err) + cellRanges.Init() + cellRanges.PushBack(cellRange{ + From: cellRef{Col: 3, Row: TotalRows, Sheet: "Sheet1"}, + To: cellRef{Col: 3, Row: TotalRows + 1, Sheet: "Sheet1"}, + }) + _, err = f.rangeResolver(&calcContext{}, cellRefs, cellRanges) + assert.Equal(t, ErrMaxRows, err) + + // Test extract value from references with invalid references + cellRanges.Init() + cellRefs.PushBack(cellRef{Col: 1, Row: 1, Sheet: "SheetN"}) + _, err = f.rangeResolver(&calcContext{}, cellRefs, cellRanges) + assert.EqualError(t, err, "sheet SheetN does not exist") + + cellRefs.Init() + cellRefs.PushBack(cellRef{Col: 1, Row: TotalRows + 1, Sheet: "SheetN"}) + _, err = f.rangeResolver(&calcContext{}, cellRefs, cellRanges) + assert.Equal(t, ErrMaxRows, err) +} + func TestNestedFunctionsWithOperators(t *testing.T) { f := NewFile() formulaList := map[string]string{