diff --git a/.config/babel/add-import-extension.js b/.config/babel/add-import-extension.js new file mode 100644 index 000000000..81231b760 --- /dev/null +++ b/.config/babel/add-import-extension.js @@ -0,0 +1,90 @@ +// Based on https://github.com/handsontable/handsontable/blob/bd7628544ff83d6e74a9cc949e2c3c38fef74d76/handsontable/.config/plugin/babel/add-import-extension.js + +const { existsSync, lstatSync } = require('fs'); +const { dirname, resolve } = require('path'); +const { types } = require('@babel/core'); +const { declare } = require('@babel/helper-plugin-utils'); + +const VALID_EXTENSIONS = ['js', 'mjs']; + +const hasExtension = moduleName => VALID_EXTENSIONS.some(ext => moduleName.endsWith(`.${ext}`)); +const isCoreJSPolyfill = moduleName => moduleName.startsWith('core-js'); +const isLocalModule = moduleName => moduleName.startsWith('.'); +const isProcessableModule = (moduleName) => { + return !hasExtension(moduleName) && (isCoreJSPolyfill(moduleName) || isLocalModule(moduleName)); +}; + +const createVisitor = ({ declaration, origArgs, extension = 'js' }) => { + return (path, { file }) => { + const { node: { source, exportKind, importKind } } = path; + const { opts: { filename } } = file; + const isTypeOnly = exportKind === 'type' || importKind === 'type'; + + if (!source || isTypeOnly || !isProcessableModule(source.value)) { + return; + } + + const { value: moduleName } = source; + const absoluteFilePath = resolve(dirname(filename), moduleName); + const finalExtension = isCoreJSPolyfill(moduleName) ? 'js' : extension; + + let newModulePath; + + // Resolves a case where "import" points to a module name which exists as a file and + // as a directory. For example in this case: + // ``` + // import { registerPlugin } from 'plugins'; + // ``` + // and with this directory structure: + // |- editors + // |- plugins + // |- filters/ + // |- ... + // +- index.js + // |- plugins.js + // |- ... + // +- index.js + // + // the plugin will rename import declaration to point to the `plugins.js` file. + if (existsSync(`${absoluteFilePath}.js`)) { + newModulePath = `${moduleName}.${finalExtension}`; + + // In a case when the file doesn't exist and the module is a directory it will + // rename to `plugins/index.js`. + } else if (existsSync(absoluteFilePath) && lstatSync(absoluteFilePath).isDirectory()) { + newModulePath = `${moduleName}/index.${finalExtension}`; + + // And for other cases it simply put the extension on the end of the module path + } else { + newModulePath = `${moduleName}.${finalExtension}`; + } + + path.replaceWith(declaration(...origArgs(path), types.stringLiteral(newModulePath))); + }; +}; + +module.exports = declare((api, options) => { + api.assertVersion(7); + + return { + name: 'add-import-extension', + visitor: { + // It covers default and named imports + ImportDeclaration: createVisitor({ + extension: options.extension, + declaration: types.importDeclaration, + origArgs: ({ node: { specifiers } }) => [specifiers], + }), + ExportNamedDeclaration: createVisitor({ + extension: options.extension, + declaration: types.exportNamedDeclaration, + origArgs: ({ node: { declaration, specifiers } }) => [declaration, specifiers], + }), + ExportAllDeclaration: createVisitor({ + extension: options.extension, + declaration: types.exportAllDeclaration, + origArgs: () => [], + }), + } + }; +}); diff --git a/.config/karma/base.js b/.config/karma/base.js index f65025814..d66811a35 100644 --- a/.config/karma/base.js +++ b/.config/karma/base.js @@ -58,6 +58,9 @@ module.exports.create = function(config) { // how many browser should be started simultaneous concurrency: Infinity, + // Extending timeout fixes https://github.com/handsontable/hyperformula/issues/1430 + browserDisconnectTimeout : 60000, + // Webpack's configuration for Karma webpack: (function() { // Take the second config from an array - full HF build. diff --git a/.config/source-license-header.js b/.config/source-license-header.js index c35e60b6e..ea945eb95 100644 --- a/.config/source-license-header.js +++ b/.config/source-license-header.js @@ -1,4 +1,4 @@ /** * @license - * Copyright (c) 2024 Handsoncode. All rights reserved. + * Copyright (c) 2025 Handsoncode. All rights reserved. */ \ No newline at end of file diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 118e2611c..4ad2abd22 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -1,4 +1,6 @@ name: Security +permissions: + contents: read on: pull_request: diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 4414a1fde..df0fc6216 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -1,4 +1,6 @@ name: Build docs +permissions: + contents: read on: pull_request: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fa875fb6b..57f2b8b20 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,6 @@ name: Build on various envs +permissions: + contents: read on: pull_request: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e727d18ea..7efe1ba2c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,4 +1,7 @@ name: "CodeQL" +permissions: + contents: read + pull-requests: write on: pull_request: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e4e01c0e0..792b2f30d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,4 +1,6 @@ name: Lint +permissions: + contents: read on: pull_request: diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 4b95b1f26..64a417635 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -1,4 +1,7 @@ name: Performance +permissions: + contents: read + pull-requests: write on: pull_request: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 56db07a81..97eacdb0a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,4 +1,7 @@ name: Publish +permissions: + contents: read + pages: write on: push: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2d5641446..1853ec7c7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,6 @@ name: Test +permissions: + contents: read on: pull_request: @@ -38,6 +40,8 @@ jobs: - name: Upload coverage to Codecov uses: codecov/codecov-action@6004246f47ab62d32be025ce173b241cd84ac58e # https://github.com/codecov/codecov-action/releases/tag/v1.0.13 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} browser-tests: strategy: diff --git a/.typedoc.ts b/.typedoc.ts index 4b46fee88..0001ced87 100644 --- a/.typedoc.ts +++ b/.typedoc.ts @@ -1,9 +1,4 @@ module.exports = { - "inputFiles": [ - "./src/HyperFormula.ts", - "./src/ConfigParams.ts", - "./src/Emitter.ts", - ], "exclude": [ "./test/**", "./src/interpreter/**", diff --git a/CHANGELOG.md b/CHANGELOG.md index bba6a38eb..b47432ccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,30 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +## [3.0.1] - 2025-08-11 + +### Fixed + +- Fixed `Edge does not exist` error when a named expression is used twice in the same formula. [#1102](https://github.com/handsontable/hyperformula/issues/1102) +- Fixed typos in the built-in functions guide. [#1517](https://github.com/handsontable/hyperformula/issues/1517) +- Fixed an issue where named expressions added on engine initialization were not updated on changes. [#1501](https://github.com/handsontable/hyperformula/issues/1501) + +## [3.0.0] - 2025-01-14 + +### Added + +- Added a new function: XLOOKUP. [#1458](https://github.com/handsontable/hyperformula/issues/1458) + +### Changed + +- **Breaking change**: Changed ES module build to use `mjs` files and `exports` property in `package.json` to make importing language files possible in Node environment. [#1344](https://github.com/handsontable/hyperformula/issues/1344) +- **Breaking change**: Changed the default value of the `precisionRounding` configuration option to `10`. [#1300](https://github.com/handsontable/hyperformula/issues/1300) +- Make methods `simpleCellAddressToString` and `simpleCellRangeToString` more logical and easier to use. [#1151](https://github.com/handsontable/hyperformula/issues/1151) + +### Removed + +- **Breaking change**: Removed the `binarySearchThreshold` configuration option. [#1439](https://github.com/handsontable/hyperformula/issues/1439) + ## [2.7.1] - 2024-07-18 ### Fixed diff --git a/README.md b/README.md index 21dfd34f4..6fe85f9cc 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,8 @@ HyperFormula doesn't assume any existing user interface, making it a general-pur - [Support for named expressions](https://hyperformula.handsontable.com/guide/named-expressions.html) - [Support for data sorting](https://hyperformula.handsontable.com/guide/sorting-data.html) - [Support for formula localization with 17 built-in languages](https://hyperformula.handsontable.com/guide/i18n-features.html) -- GPLv3 license +- Easy integration with any front-end or back-end application +- GPLv3 or a [commercial license](https://handsontable.com/get-a-quote) - Maintained by the team that stands behind the [Handsontable](https://handsontable.com/) data grid ## Documentation @@ -97,7 +98,7 @@ hf.setCellContents({ sheet: sheetId, row: 0, col: 0 }, [['Monthly Payment', '=PM console.log(`${hf.getCellValue({ sheet: sheetId, row: 0, col: 0 })}: ${hf.getCellValue({ sheet: sheetId, row: 0, col: 1 })}`); ``` -[Run this code in CodeSandbox](https://codesandbox.io/p/sandbox/github/handsontable/hyperformula-demos/tree/2.7.x/mortgage-calculator) +[Run this code in StackBlitz](https://stackblitz.com/github/handsontable/hyperformula-demos/tree/3.0.x/mortgage-calculator) ## Contributing diff --git a/babel.config.js b/babel.config.js index e7a33d37d..ca5739e2b 100644 --- a/babel.config.js +++ b/babel.config.js @@ -9,7 +9,7 @@ module.exports = { ['@babel/preset-env', { modules: false, useBuiltIns: 'usage', - corejs: '3.23', + corejs: '3.39.0', }] ], plugins: [ @@ -18,7 +18,7 @@ module.exports = { helpers: false, regenerator: false, useESModules: false, - version: '^7.18.9', + version: '^7.25.9', }], ['@babel/plugin-transform-modules-commonjs', { loose: true }] ] @@ -31,7 +31,9 @@ module.exports = { }, // Environment for transpiling files to be compatible with ES Modules. es: { - plugins: [], + plugins: [ + ['./.config/babel/add-import-extension.js', { extension: 'mjs' }], + ], }, }, }; diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index e724f92f2..1671b73a7 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -12,12 +12,12 @@ module.exports = { title: 'HyperFormula (v' + HyperFormula.version + ')', description: 'HyperFormula is an open-source, high-performance calculation engine for spreadsheets and web applications.', head: [ - // Robots for staging: noindex, nofollow - ['meta', {name: 'robots', content: 'noindex, nofollow'}], + // Robots for staging: noindex, nofollow + ['meta', {name: 'robots', content: 'noindex, nofollow'}], // Import HF (required for the examples) [ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula/dist/hyperformula.full.min.js' } ], - [ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula@2.7.1/dist/languages/enUS.js' } ], - [ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula@2.7.1/dist/languages/frFR.js' } ], + [ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula/dist/languages/enUS.js' } ], + [ 'script', { src: 'https://cdn.jsdelivr.net/npm/hyperformula/dist/languages/frFR.js' } ], // Import moment (required for the examples) [ 'script', { src: 'https://cdn.jsdelivr.net/npm/moment/moment.min.js' } ], // Google Tag Manager, an extra element within the `ssr.html` file. @@ -175,6 +175,7 @@ module.exports = { title: 'Overview', collapsable: false, children: [ + ['/guide/quality', 'Quality'], ['/guide/supported-browsers', 'Supported browsers'], ['/guide/dependencies', 'Dependencies'], ['/guide/licensing', 'Licensing'], @@ -267,7 +268,8 @@ module.exports = { children: [ ['/guide/release-notes', 'Release notes'], ['/guide/migration-from-0.6-to-1.0', 'Migrating from 0.6 to 1.0'], - ['/guide/migration-from-1.0-to-2.0', 'Migrating from 1.x to 2.0'], + ['/guide/migration-from-1.x-to-2.0', 'Migrating from 1.x to 2.0'], + ['/guide/migration-from-2.x-to-3.0', 'Migrating from 2.x to 3.0'], ] }, { diff --git a/docs/examples/advanced-usage/example1.css b/docs/examples/advanced-usage/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/advanced-usage/example1.css +++ b/docs/examples/advanced-usage/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/advanced-usage/example1.js b/docs/examples/advanced-usage/example1.js index 564a58c6f..40019f447 100644 --- a/docs/examples/advanced-usage/example1.js +++ b/docs/examples/advanced-usage/example1.js @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -67,7 +67,7 @@ hf.setSheetContent(hf.getSheetId(sheetInfo.formulas.sheetName), formulasData); function renderTable(sheetName) { const sheetId = hf.getSheetId(sheetName); const tbodyDOM = document.querySelector( - `.example #${sheetName}-container tbody` + `.example #${sheetName}-container tbody`, ); const { height, width } = hf.getSheetDimensions(sheetId); @@ -101,7 +101,7 @@ function renderResult() { const resultOutputDOM = document.querySelector('.example #output'); const cellAddress = hf.simpleCellAddressFromString( `${sheetInfo.formulas.sheetName}!A1`, - hf.getSheetId(sheetInfo.formulas.sheetName) + hf.getSheetId(sheetInfo.formulas.sheetName), ); resultOutputDOM.innerHTML = ` diff --git a/docs/examples/advanced-usage/example1.ts b/docs/examples/advanced-usage/example1.ts index fe2519e41..86b68c9c7 100644 --- a/docs/examples/advanced-usage/example1.ts +++ b/docs/examples/advanced-usage/example1.ts @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -69,7 +69,7 @@ hf.setSheetContent(hf.getSheetId(sheetInfo.formulas.sheetName), formulasData); function renderTable(sheetName) { const sheetId = hf.getSheetId(sheetName); const tbodyDOM = document.querySelector( - `.example #${sheetName}-container tbody` + `.example #${sheetName}-container tbody`, ); const { height, width } = hf.getSheetDimensions(sheetId); @@ -103,7 +103,7 @@ function renderResult() { const resultOutputDOM = document.querySelector('.example #output'); const cellAddress = hf.simpleCellAddressFromString( `${sheetInfo.formulas.sheetName}!A1`, - hf.getSheetId(sheetInfo.formulas.sheetName) + hf.getSheetId(sheetInfo.formulas.sheetName), ); resultOutputDOM.innerHTML = ` diff --git a/docs/examples/basic-operations/example1.css b/docs/examples/basic-operations/example1.css index ef0730e92..56fc8365c 100644 --- a/docs/examples/basic-operations/example1.css +++ b/docs/examples/basic-operations/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/basic-operations/example1.js b/docs/examples/basic-operations/example1.js index a0ecad379..47001113d 100644 --- a/docs/examples/basic-operations/example1.js +++ b/docs/examples/basic-operations/example1.js @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -188,9 +188,7 @@ function renderTable() { cellValue = hf.getCellFormula(cellAddress); } - newTbodyHTML += ` + newTbodyHTML += ` ${cellValue} `; } @@ -213,9 +211,7 @@ function updateSheetDropdown() { sheetNames.forEach((sheetName) => { const isCurrent = sheetName === state.currentSheet; - dropdownContent += ``; + dropdownContent += ``; }); sheetDropdownDOM.innerHTML = dropdownContent; } @@ -332,7 +328,7 @@ function doAction(action) { handleError(() => { hf.setSheetContent( hf.getSheetId(state.currentSheet), - getSampleData(5, 5) + getSampleData(5, 5), ); }); updateSheetDropdown(); @@ -398,7 +394,7 @@ function doAction(action) { cellAddress = handleError(() => { return hf.simpleCellAddressFromString( inputValues[0], - hf.getSheetId(state.currentSheet) + hf.getSheetId(state.currentSheet), ); }, 'Invalid cell address format.'); @@ -413,7 +409,7 @@ function doAction(action) { cellAddress = handleError(() => { return hf.simpleCellAddressFromString( inputValues[0], - hf.getSheetId(state.currentSheet) + hf.getSheetId(state.currentSheet), ); }, 'Invalid cell address format.'); diff --git a/docs/examples/basic-operations/example1.ts b/docs/examples/basic-operations/example1.ts index ca2b9e24f..61ca3e24c 100644 --- a/docs/examples/basic-operations/example1.ts +++ b/docs/examples/basic-operations/example1.ts @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -343,7 +343,7 @@ function doAction(action) { handleError(() => { hf.setSheetContent( hf.getSheetId(state.currentSheet), - getSampleData(5, 5) + getSampleData(5, 5), ); }); @@ -415,7 +415,7 @@ function doAction(action) { cellAddress = handleError(() => { return hf.simpleCellAddressFromString( inputValues[0], - hf.getSheetId(state.currentSheet) + hf.getSheetId(state.currentSheet), ); }, 'Invalid cell address format.'); @@ -430,7 +430,7 @@ function doAction(action) { cellAddress = handleError(() => { return hf.simpleCellAddressFromString( inputValues[0], - hf.getSheetId(state.currentSheet) + hf.getSheetId(state.currentSheet), ); }, 'Invalid cell address format.'); diff --git a/docs/examples/basic-usage/example1.css b/docs/examples/basic-usage/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/basic-usage/example1.css +++ b/docs/examples/basic-usage/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/basic-usage/example1.js b/docs/examples/basic-usage/example1.js index 4484b6bba..70e2a3185 100644 --- a/docs/examples/basic-usage/example1.js +++ b/docs/examples/basic-usage/example1.js @@ -3,14 +3,14 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ const tableData = [['10', '20', '=SUM(A1,B1)']]; // Create an empty HyperFormula instance. const hf = HyperFormula.buildEmpty({ - precisionRounding: 10, + precisionRounding: 9, licenseKey: 'gpl-v3', }); @@ -25,7 +25,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); /** diff --git a/docs/examples/basic-usage/example1.ts b/docs/examples/basic-usage/example1.ts index 3901624e5..8266f5e36 100644 --- a/docs/examples/basic-usage/example1.ts +++ b/docs/examples/basic-usage/example1.ts @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -11,7 +11,7 @@ const tableData = [['10', '20', '=SUM(A1,B1)']]; // Create an empty HyperFormula instance. const hf = HyperFormula.buildEmpty({ - precisionRounding: 10, + precisionRounding: 9, licenseKey: 'gpl-v3', }); @@ -26,7 +26,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); /** diff --git a/docs/examples/batch-operations/example1.css b/docs/examples/batch-operations/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/batch-operations/example1.css +++ b/docs/examples/batch-operations/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/batch-operations/example1.js b/docs/examples/batch-operations/example1.js index 72a98595a..15ac04606 100644 --- a/docs/examples/batch-operations/example1.js +++ b/docs/examples/batch-operations/example1.js @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -40,7 +40,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Add named expressions for the "TOTAL" row. hf.addNamedExpression('Year_1', '=SUM(main!$B$1:main!$B$5)'); @@ -78,9 +78,7 @@ function renderTable(calculated = false) { cellValue = hf.getCellFormula(cellAddress); } - newTbodyHTML += ` + newTbodyHTML += ` ${cellValue} `; } diff --git a/docs/examples/batch-operations/example1.ts b/docs/examples/batch-operations/example1.ts index d6501f5fd..c2cadc1f4 100644 --- a/docs/examples/batch-operations/example1.ts +++ b/docs/examples/batch-operations/example1.ts @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -40,7 +40,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Add named expressions for the "TOTAL" row. diff --git a/docs/examples/clipboard-operations/example1.css b/docs/examples/clipboard-operations/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/clipboard-operations/example1.css +++ b/docs/examples/clipboard-operations/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/clipboard-operations/example1.js b/docs/examples/clipboard-operations/example1.js index 6cd3f1f1d..cf91eef53 100644 --- a/docs/examples/clipboard-operations/example1.js +++ b/docs/examples/clipboard-operations/example1.js @@ -3,10 +3,13 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ +/* start:skip-in-sandbox */ +const NothingToPasteError = HyperFormula.NothingToPasteError; +/* end:skip-in-sandbox */ /** * Initial table data. */ @@ -35,7 +38,7 @@ function reinitializeData() { col: 0, sheet: sheetId, }, - tableData + tableData, ); } @@ -53,7 +56,6 @@ function bindEvents() { }); pasteButton.addEventListener('click', () => { paste(); - updateCopyInfo('Pasted into the first row'); }); resetButton.addEventListener('click', () => { reinitializeData(); @@ -76,8 +78,17 @@ function copy() { * Paste the HF clipboard into the first row. */ function paste() { - hf.paste({ sheet: 0, col: 0, row: 0 }); - renderTable(); + try { + hf.paste({ sheet: 0, col: 0, row: 0 }); + updateCopyInfo('Pasted into the first row'); + renderTable(); + } catch (error) { + if (error instanceof NothingToPasteError) { + updateCopyInfo('There is nothing to paste'); + } else { + throw error; + } + } } const ANIMATION_ENABLED = true; diff --git a/docs/examples/clipboard-operations/example1.ts b/docs/examples/clipboard-operations/example1.ts index c0c67e07f..f1672de31 100644 --- a/docs/examples/clipboard-operations/example1.ts +++ b/docs/examples/clipboard-operations/example1.ts @@ -1,12 +1,16 @@ /* start:skip-in-compilation */ -import HyperFormula from 'hyperformula'; +import HyperFormula, { NothingToPasteError } from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ +/* start:skip-in-sandbox */ +const NothingToPasteError = HyperFormula.NothingToPasteError; +/* end:skip-in-sandbox */ + /** * Initial table data. */ @@ -35,7 +39,7 @@ function reinitializeData() { col: 0, sheet: sheetId, }, - tableData + tableData, ); } @@ -54,7 +58,6 @@ function bindEvents() { pasteButton.addEventListener('click', () => { paste(); - updateCopyInfo('Pasted into the first row'); }); resetButton.addEventListener('click', () => { @@ -78,8 +81,17 @@ function copy() { * Paste the HF clipboard into the first row. */ function paste() { - hf.paste({ sheet: 0, col: 0, row: 0 }); - renderTable(); + try { + hf.paste({ sheet: 0, col: 0, row: 0 }); + updateCopyInfo('Pasted into the first row'); + renderTable(); + } catch (error: unknown) { + if (error instanceof NothingToPasteError) { + updateCopyInfo('There is nothing to paste'); + } else { + throw error; + } + } } const ANIMATION_ENABLED = true; diff --git a/docs/examples/date-time/example1.css b/docs/examples/date-time/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/date-time/example1.css +++ b/docs/examples/date-time/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/date-time/example1.js b/docs/examples/date-time/example1.js index 01d646fec..f4628ba73 100644 --- a/docs/examples/date-time/example1.js +++ b/docs/examples/date-time/example1.js @@ -4,7 +4,7 @@ import moment from 'moment'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -61,7 +61,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); /** @@ -82,9 +82,7 @@ function renderTable(calculated = false) { const showFormula = calculated || !cellHasFormula; const cellValue = displayValue(cellAddress, showFormula); - newTbodyHTML += ` + newTbodyHTML += ` ${cellValue} `; } diff --git a/docs/examples/date-time/example1.ts b/docs/examples/date-time/example1.ts index b9fe3adde..2db478297 100644 --- a/docs/examples/date-time/example1.ts +++ b/docs/examples/date-time/example1.ts @@ -4,7 +4,7 @@ import moment from 'moment'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -62,7 +62,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); /** diff --git a/docs/examples/demo/example1.css b/docs/examples/demo/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/demo/example1.css +++ b/docs/examples/demo/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/demo/example1.js b/docs/examples/demo/example1.js index 992116378..aee5aaf6f 100644 --- a/docs/examples/demo/example1.js +++ b/docs/examples/demo/example1.js @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -37,7 +37,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Add named expressions for the "TOTAL" row. hf.addNamedExpression('Year_1', '=SUM(main!$B$1:main!$B$5)'); @@ -88,9 +88,7 @@ function renderTable(calculated = false) { cellValue = hf.getCellFormula(cellAddress); } - newTbodyHTML += ` + newTbodyHTML += ` ${cellValue} `; } @@ -101,14 +99,10 @@ function renderTable(calculated = false) { totalRowsHTML = ` TOTAL - ${ - calculated ? hf.calculateFormula(totals[0], sheetId).toFixed(2) : totals[0] - } + ${calculated ? hf.calculateFormula(totals[0], sheetId).toFixed(2) : totals[0]} - ${ - calculated ? hf.calculateFormula(totals[1], sheetId).toFixed(2) : totals[1] - } + ${calculated ? hf.calculateFormula(totals[1], sheetId).toFixed(2) : totals[1]} `; diff --git a/docs/examples/demo/example1.ts b/docs/examples/demo/example1.ts index 15cf8ec0e..775fc4aa2 100644 --- a/docs/examples/demo/example1.ts +++ b/docs/examples/demo/example1.ts @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -37,7 +37,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Add named expressions for the "TOTAL" row. diff --git a/docs/examples/i18n/example1.css b/docs/examples/i18n/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/i18n/example1.css +++ b/docs/examples/i18n/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/i18n/example1.js b/docs/examples/i18n/example1.js index f4fa847a4..16967ff0e 100644 --- a/docs/examples/i18n/example1.js +++ b/docs/examples/i18n/example1.js @@ -4,7 +4,7 @@ import moment from 'moment'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -65,7 +65,9 @@ const config = { licenseKey: 'gpl-v3', }; -HyperFormula.registerLanguage('enUS', enUS); +if (!HyperFormula.getRegisteredLanguagesCodes().includes('enUS')) { + HyperFormula.registerLanguage('enUS', enUS); +} // Create an empty HyperFormula instance. const hf = HyperFormula.buildEmpty(config); @@ -80,7 +82,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); const columnTypes = ['string', 'time', 'date', 'number', 'currency']; @@ -164,9 +166,7 @@ function renderTable(calculated = false) { ? hf.getCellFormula(cellAddress) : formatCellValue(cellAddress); - newTbodyHTML += `${displayValue}`; + newTbodyHTML += `${displayValue}`; } newTbodyHTML += ''; diff --git a/docs/examples/i18n/example1.ts b/docs/examples/i18n/example1.ts index 676756397..a59236f60 100644 --- a/docs/examples/i18n/example1.ts +++ b/docs/examples/i18n/example1.ts @@ -5,7 +5,7 @@ import moment from 'moment'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -67,7 +67,9 @@ const config = { licenseKey: 'gpl-v3', }; -HyperFormula.registerLanguage('enUS', enUS); +if (!HyperFormula.getRegisteredLanguagesCodes().includes('enUS')) { + HyperFormula.registerLanguage('enUS', enUS); +} // Create an empty HyperFormula instance. const hf = HyperFormula.buildEmpty(config); @@ -83,7 +85,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); const columnTypes = ['string', 'time', 'date', 'number', 'currency']; diff --git a/docs/examples/localizing-functions/example1.css b/docs/examples/localizing-functions/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/localizing-functions/example1.css +++ b/docs/examples/localizing-functions/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/localizing-functions/example1.js b/docs/examples/localizing-functions/example1.js index 98d81e5b8..d7388ac47 100644 --- a/docs/examples/localizing-functions/example1.js +++ b/docs/examples/localizing-functions/example1.js @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -28,7 +28,9 @@ const tableData = [ ]; // register language -HyperFormula.registerLanguage('frFR', frFR); +if (!HyperFormula.getRegisteredLanguagesCodes().includes('frFR')) { + HyperFormula.registerLanguage('frFR', frFR); +} // Create an empty HyperFormula instance. const hf = HyperFormula.buildEmpty({ @@ -47,7 +49,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Add named expressions for the "TOTAL" row. hf.addNamedExpression('Year_1', '=SOMME(main!$B$1:main!$B$5)'); @@ -83,9 +85,7 @@ function renderTable(calculated = false) { cellValue = hf.getCellFormula(cellAddress); } - newTbodyHTML += ` + newTbodyHTML += ` ${cellValue} `; } @@ -96,14 +96,10 @@ function renderTable(calculated = false) { totalRowsHTML = ` TOTAL - ${ - calculated ? hf.calculateFormula(totals[0], sheetId).toFixed(2) : totals[0] - } + ${calculated ? hf.calculateFormula(totals[0], sheetId).toFixed(2) : totals[0]} - ${ - calculated ? hf.calculateFormula(totals[1], sheetId).toFixed(2) : totals[1] - } + ${calculated ? hf.calculateFormula(totals[1], sheetId).toFixed(2) : totals[1]} `; diff --git a/docs/examples/localizing-functions/example1.ts b/docs/examples/localizing-functions/example1.ts index b224f3cb1..daa70fe05 100644 --- a/docs/examples/localizing-functions/example1.ts +++ b/docs/examples/localizing-functions/example1.ts @@ -4,7 +4,7 @@ import frFR from 'hyperformula/es/i18n/languages/frFR'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -30,7 +30,9 @@ const tableData = [ ]; // register language -HyperFormula.registerLanguage('frFR', frFR); +if (!HyperFormula.getRegisteredLanguagesCodes().includes('frFR')) { + HyperFormula.registerLanguage('frFR', frFR); +} // Create an empty HyperFormula instance. const hf = HyperFormula.buildEmpty({ @@ -49,7 +51,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Add named expressions for the "TOTAL" row. diff --git a/docs/examples/named-expressions/example1.css b/docs/examples/named-expressions/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/named-expressions/example1.css +++ b/docs/examples/named-expressions/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/named-expressions/example1.js b/docs/examples/named-expressions/example1.js index 7917f7252..938899136 100644 --- a/docs/examples/named-expressions/example1.js +++ b/docs/examples/named-expressions/example1.js @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -34,7 +34,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Add named expressions hf.addNamedExpression('myOneCell', '=main!$A$1'); @@ -71,9 +71,7 @@ function renderTable(calculated = false) { cellValue = hf.getCellFormula(cellAddress); } - newTbodyHTML += ` + newTbodyHTML += ` ${cellValue} `; } diff --git a/docs/examples/named-expressions/example1.ts b/docs/examples/named-expressions/example1.ts index 594ecdaa0..e802ed4a3 100644 --- a/docs/examples/named-expressions/example1.ts +++ b/docs/examples/named-expressions/example1.ts @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -34,7 +34,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Add named expressions diff --git a/docs/examples/sorting-data/example1.css b/docs/examples/sorting-data/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/sorting-data/example1.css +++ b/docs/examples/sorting-data/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/sorting-data/example1.js b/docs/examples/sorting-data/example1.js index 97c2bfe97..1abb485ea 100644 --- a/docs/examples/sorting-data/example1.js +++ b/docs/examples/sorting-data/example1.js @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -37,7 +37,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); /** @@ -100,9 +100,7 @@ function renderTable(calculated = false) { cellValue = hf.getCellFormula(cellAddress); } - newTbodyHTML += ` + newTbodyHTML += ` ${cellValue} `; } diff --git a/docs/examples/sorting-data/example1.ts b/docs/examples/sorting-data/example1.ts index 8454d6382..00cd2cdf5 100644 --- a/docs/examples/sorting-data/example1.ts +++ b/docs/examples/sorting-data/example1.ts @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -37,7 +37,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); /** diff --git a/docs/examples/undo-redo/example1.css b/docs/examples/undo-redo/example1.css index 224282eb7..2581c230c 100644 --- a/docs/examples/undo-redo/example1.css +++ b/docs/examples/undo-redo/example1.css @@ -3,7 +3,7 @@ color: #606c76; font-family: sans-serif; font-size: 14px; - font-weight: 300; + font-weight: 400; letter-spacing: .01em; line-height: 1.6; -webkit-box-sizing: border-box; diff --git a/docs/examples/undo-redo/example1.js b/docs/examples/undo-redo/example1.js index 9a3be5b48..92f191f70 100644 --- a/docs/examples/undo-redo/example1.js +++ b/docs/examples/undo-redo/example1.js @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -31,7 +31,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Clear the undo stack to prevent undoing the initialization steps. hf.clearUndoStack(); diff --git a/docs/examples/undo-redo/example1.ts b/docs/examples/undo-redo/example1.ts index 3b03b8034..03f0b313f 100644 --- a/docs/examples/undo-redo/example1.ts +++ b/docs/examples/undo-redo/example1.ts @@ -3,7 +3,7 @@ import HyperFormula from 'hyperformula'; console.log( `%c Using HyperFormula ${HyperFormula.version}`, - 'color: blue; font-weight: bold' + 'color: blue; font-weight: bold', ); /* end:skip-in-compilation */ @@ -31,7 +31,7 @@ hf.setCellContents( col: 0, sheet: sheetId, }, - tableData + tableData, ); // Clear the undo stack to prevent undoing the initialization steps. diff --git a/docs/guide/built-in-functions.md b/docs/guide/built-in-functions.md index 1ed8e18fb..adb05c579 100644 --- a/docs/guide/built-in-functions.md +++ b/docs/guide/built-in-functions.md @@ -112,15 +112,15 @@ Total number of functions: **{{ $page.functionsCount }}** | HEX2BIN | The result is the binary number for the hexadecimal number entered. | HEX2BIN(Number, Places) | | HEX2DEC | The result is the decimal number for the hexadecimal number entered. | HEX2DEC(Number) | | HEX2OCT | The result is the octal number for the hexadecimal number entered. | HEX2OCT(Number, Places) | -| IMABS | Returns module of a complex number. | IMABS(Complex) | +| IMABS | Returns modulus of a complex number. | IMABS(Complex) | | IMAGINARY | Returns imaginary part of a complex number. | IMAGINARY(Complex) | | IMARGUMENT | Returns argument of a complex number. | IMARGUMENT(Complex) | | IMCONJUGATE | Returns conjugate of a complex number. | IMCONJUGATE(Complex) | | IMCOS | Returns cosine of a complex number. | IMCOS(Complex) | | IMCOSH | Returns hyperbolic cosine of a complex number. | IMCOSH(Complex) | -| IMCOT | Returns cotangens of a complex number. | IMCOT(Complex) | -| IMCSC | Returns cosecans of a complex number. | IMCSC(Complex) | -| IMCSCH | Returns hyperbolic cosecans of a complex number. | IMCSCH(Complex) | +| IMCOT | Returns cotangent of a complex number. | IMCOT(Complex) | +| IMCSC | Returns cosecant of a complex number. | IMCSC(Complex) | +| IMCSCH | Returns hyperbolic cosecant of a complex number. | IMCSCH(Complex) | | IMDIV | Divides two complex numbers. | IMDIV(Complex1, Complex2) | | IMEXP | Returns exponent of a complex number. | IMEXP(Complex) | | IMLN | Returns natural logarithm of a complex number. | IMLN(Complex) | @@ -212,21 +212,22 @@ Total number of functions: **{{ $page.functionsCount }}** ### Lookup and reference -| Function ID | Description | Syntax | -|:------------|:-----------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------| -| ADDRESS | Returns a cell reference as a string. | ADDRESS(Row, Column[, AbsoluteRelativeMode[, UseA1Notation[, Sheet]]]) | -| CHOOSE | Uses an index to return a value from a list of values. | CHOOSE(Index, Value1, Value2, ...ValueN) | -| COLUMN | Returns column number of a given reference or formula reference if argument not provided. | COLUMNS([Reference]) | -| COLUMNS | Returns the number of columns in the given reference. | COLUMNS(Array) | -| FORMULATEXT | Returns a formula in a given cell as a string. | FORMULATEXT(Reference) | -| HLOOKUP | Searches horizontally with reference to adjacent cells to the bottom. | HLOOKUP(Search_Criterion, Array, Index, Sort_Order) | -| HYPERLINK | Stores the url in the cell's metadata. It can be read using method [`getCellHyperlink`](../api/classes/hyperformula.md#getcellhyperlink) | HYPERLINK(Url[, LinkLabel]) | -| INDEX | Returns the contents of a cell specified by row and column number. The column number is optional and defaults to 1. | INDEX(Range, Row [, Column]) | -| MATCH | Returns the relative position of an item in an array that matches a specified value. | MATCH(Searchcriterion, Lookuparray [, MatchType]) | -| OFFSET | Returns the value of a cell offset by a certain number of rows and columns from a given reference point. | OFFSET(Reference, Rows, Columns, Height, Width) | -| ROW | Returns row number of a given reference or formula reference if argument not provided. | ROW([Reference]) | -| ROWS | Returns the number of rows in the given reference. | ROWS(Array) | -| VLOOKUP | Searches vertically with reference to adjacent cells to the right. | VLOOKUP(Search_Criterion, Array, Index, Sort_Order) | +| Function ID | Description | Syntax | +|:------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------| +| ADDRESS | Returns a cell reference as a string. | ADDRESS(Row, Column[, AbsoluteRelativeMode[, UseA1Notation[, Sheet]]]) | +| CHOOSE | Uses an index to return a value from a list of values. | CHOOSE(Index, Value1, Value2, ...ValueN) | +| COLUMN | Returns column number of a given reference or formula reference if argument not provided. | COLUMNS([Reference]) | +| COLUMNS | Returns the number of columns in the given reference. | COLUMNS(Array) | +| FORMULATEXT | Returns a formula in a given cell as a string. | FORMULATEXT(Reference) | +| HLOOKUP | Searches horizontally with reference to adjacent cells to the bottom. | HLOOKUP(Search_Criterion, Array, Index, Sort_Order) | +| HYPERLINK | Stores the url in the cell's metadata. It can be read using method [`getCellHyperlink`](../api/classes/hyperformula.md#getcellhyperlink) | HYPERLINK(Url[, LinkLabel]) | +| INDEX | Returns the contents of a cell specified by row and column number. The column number is optional and defaults to 1. | INDEX(Range, Row [, Column]) | +| MATCH | Returns the relative position of an item in an array that matches a specified value. | MATCH(Searchcriterion, LookupArray [, MatchType]) | +| OFFSET | Returns the value of a cell offset by a certain number of rows and columns from a given reference point. | OFFSET(Reference, Rows, Columns, Height, Width) | +| ROW | Returns row number of a given reference or formula reference if argument not provided. | ROW([Reference]) | +| ROWS | Returns the number of rows in the given reference. | ROWS(Array) | +| VLOOKUP | Searches vertically with reference to adjacent cells to the right. | VLOOKUP(Search_Criterion, Array, Index, Sort_Order) | +| XLOOKUP | Searches for a key in a range and returns the item corresponding to the match it finds. If no match exists, then XLOOKUP can return the closest (approximate) match. | XLOOKUP(LookupValue, LookupArray, ReturnArray, [IfNotFound], [MatchMode], [SearchMode]) | ### Math and trigonometry @@ -254,7 +255,7 @@ Total number of functions: **{{ $page.functionsCount }}** | COT | Returns the cotangent of the given angle (in radians). | COT(Number) | | COTH | Returns the hyperbolic cotangent of the given value. | COTH(Number) | | COUNTUNIQUE | Counts the number of unique values in a list of specified values and ranges. | COUNTUNIQUE(Value1, Value2, ...ValueN) | -| CSC | Returns the cosecans of the given angle (in radians). | CSC(Number) | +| CSC | Returns the cosecant of the given angle (in radians). | CSC(Number) | | CSCH | Returns the hyperbolic cosecant of the given value. | CSCH(Number) | | DECIMAL | Converts text with characters from a number system to a positive integer in the base radix given. | DECIMAL("Text", Radix) | | DEGREES | Converts radians into degrees. | DEGREES(Number) | @@ -268,7 +269,7 @@ Total number of functions: **{{ $page.functionsCount }}** | GCD | Computes greatest common divisor of numbers. | GCD(Number1, Number2, ...NumberN) | | INT | Rounds a number down to the nearest integer. | INT(Number) | | ISO.CEILING | Rounds a number up to the nearest multiple of Significance. | ISO.CEILING(Number[, Significance]) | -| LCM | Computes least common multiplicity of numbers. | LCM(Number1, Number2, ...NumberN) | +| LCM | Computes least common multiple of numbers. | LCM(Number1, Number2, ...NumberN) | | LN | Returns the natural logarithm based on the constant e of a number. | LN(Number) | | LOG | Returns the logarithm of a number to the specified base. | LOG(Number, Base) | | LOG10 | Returns the base-10 logarithm of a number. | LOG10(Number) | @@ -349,8 +350,8 @@ Total number of functions: **{{ $page.functionsCount }}** | BESSELJ | Returns value of Bessel function. | BESSELJ(x, n) | | BESSELK | Returns value of Bessel function. | BESSELK(x, n) | | BESSELY | Returns value of Bessel function. | BESSELY(x, n) | -| BETA.DIST | Returns the denisty of Beta distribution. | BETA.DIST(Number1, Number2, Number3, Boolean[, Number4[, Number5]]) | -| BETADIST | Returns the denisty of Beta distribution. | BETADIST(Number1, Number2, Number3, Boolean[, Number4[, Number5]]) | +| BETA.DIST | Returns the density of Beta distribution. | BETA.DIST(Number1, Number2, Number3, Boolean[, Number4[, Number5]]) | +| BETADIST | Returns the density of Beta distribution. | BETADIST(Number1, Number2, Number3, Boolean[, Number4[, Number5]]) | | BETA.INV | Returns the inverse Beta distribution value. | BETA.INV(Number1, Number2, Number3[, Number4[, Number5]]) | | BETAINV | Returns the inverse of Beta distribution value. | BETAINV(Number1, Number2, Number3[, Number4[, Number5]]) | | BINOM.DIST | Returns density of binomial distribution. | BINOM.DIST(Number1, Number2, Number3, Boolean) | @@ -403,7 +404,7 @@ Total number of functions: **{{ $page.functionsCount }}** | GAMMALN.PRECISE | Returns natural logarithm of Gamma function. | GAMMALN.PRECISE(Number) | | GAMMA.INV | Returns inverse Gamma distribution value. | GAMMA.INV(Number1, Number2, Number3) | | GAMMAINV | Returns inverse Gamma distribution value. | GAMMAINV(Number1, Number2, Number3) | -| GAUSS | Returns the probability of gaussian variable fall more than this many times standard deviation from mean. | GAUSS(Number) | +| GAUSS | Returns the probability of gaussian variable falling more than this many times standard deviation from mean. | GAUSS(Number) | | GEOMEAN | Returns the geometric average. | GEOMEAN(Number1, Number2, ...NumberN) | | HARMEAN | Returns the harmonic average. | HARMEAN(Number1, Number2, ...NumberN) | | HYPGEOMDIST | Returns density of hypergeometric distribution. | HYPGEOMDIST(Number1, Number2, Number3, Number4, Boolean) | diff --git a/docs/guide/cell-references.md b/docs/guide/cell-references.md index e2662ee2b..b3b286bda 100644 --- a/docs/guide/cell-references.md +++ b/docs/guide/cell-references.md @@ -205,6 +205,25 @@ In contrast to Google Sheets or Microsoft Excel, HyperFormula doesn't treat sing - [Types of operators: Reference operators](/guide/types-of-operators.md#reference-operators) - [API reference: Ranges](/api/classes/hyperformula.md#ranges) +## Sheet names in references + +When referencing cells or ranges from different sheets, you can specify the sheet name using the following syntax: + +``` +=SheetName!CellReference +``` + +If a sheet name contains any character other than `[A-Za-z\u00C0-\u02AF0-9_]`, it must be enclosed in single quotes. E.g.: +```javascript +=Data2023!A1 +=Sheet_1!B2 +=ÄöüSheet!C3 +='My Sheet'!A1 +='Sales-2023'!B2 +='Data (Q1)'!C3 +='Sheet #1'!D4 +``` + ## Circular references Since HyperFormula does not embed any UI, it allows for the input of a circular reference into a cell. Compared to popular spreadsheets, diff --git a/docs/guide/compatibility-with-microsoft-excel.md b/docs/guide/compatibility-with-microsoft-excel.md index 9f96283d4..65f252f4e 100644 --- a/docs/guide/compatibility-with-microsoft-excel.md +++ b/docs/guide/compatibility-with-microsoft-excel.md @@ -1,6 +1,6 @@ # Compatibility with Microsoft Excel -Achieve nearly full compatibility wih Microsoft Excel, using the right HyperFormula configuration. +Achieve nearly full compatibility with Microsoft Excel, using the right HyperFormula configuration. **Contents:** [[toc]] diff --git a/docs/guide/configuration-options.md b/docs/guide/configuration-options.md index 73a082a8d..4f3076065 100644 --- a/docs/guide/configuration-options.md +++ b/docs/guide/configuration-options.md @@ -17,7 +17,7 @@ static method called to initiate a new instance of HyperFormula. // define options const options = { licenseKey: 'gpl-v3', - precisionRounding: 10, + precisionRounding: 9, nullDate: { year: 1900, month: 1, day: 1 }, functionArgSeparator: '.' }; diff --git a/docs/guide/custom-functions.md b/docs/guide/custom-functions.md index 14ace0edd..3444cdacd 100644 --- a/docs/guide/custom-functions.md +++ b/docs/guide/custom-functions.md @@ -363,7 +363,7 @@ This demo contains the implementation of both the [`DOUBLE_RANGE`](#advanced-custom-function-example) custom functions.