# 資料驗證

- Human documentation: [https://docs.univer.ai/zh-TW/guides/sheets/features/data-validation](https://docs.univer.ai/zh-TW/guides/sheets/features/data-validation)

- Agent Markdown: [https://docs.univer.ai/zh-TW/guides/sheets/features/data-validation.md](https://docs.univer.ai/zh-TW/guides/sheets/features/data-validation.md)

- Requested language: `zh-TW`

- Content language: `zh-TW`

- Documentation version: `1.2.0`

- Source: [sheets/features/data-validation.zh-TW.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/features/data-validation.zh-TW.mdx)

---

#### Package metadata

```json
{
  "preset": [
    {
      "client": "@univerjs/preset-sheets-data-validation",
      "locale": "@univerjs/preset-sheets-data-validation/locales/zh-TW",
      "style": "@univerjs/preset-sheets-data-validation/lib/index.css"
    }
  ],
  "plugins": [
    {
      "client": "@univerjs/data-validation",
      "locale": "@univerjs/data-validation/locale/zh-TW"
    },
    {
      "client": "@univerjs/sheets-data-validation",
      "facade": "@univerjs/sheets-data-validation/facade",
      "locale": "@univerjs/sheets-data-validation/locale/zh-TW"
    },
    {
      "client": "@univerjs/sheets-data-validation-ui",
      "locale": "@univerjs/sheets-data-validation-ui/locale/zh-TW",
      "style": "@univerjs/sheets-data-validation-ui/lib/index.css"
    }
  ],
  "mobile": true,
  "server": false
}
```

資料驗證是一種在單元格中設定規則的功能，以確保輸入的資料符合特定要求。它可以幫助使用者避免輸入錯誤，提高資料的準確性和一致性。

目前支援以下資料驗證型別：

* 數字
* 整數
* 文字長度
* 日期
* 核取方塊
* 下拉選單(單選/多選)
* 自訂公式

## 外掛模式

### 安裝

#### npm

```bash
npm install @univerjs/data-validation @univerjs/sheets-data-validation @univerjs/sheets-data-validation-ui
```

#### pnpm

```bash
pnpm add @univerjs/data-validation @univerjs/sheets-data-validation @univerjs/sheets-data-validation-ui
```

#### yarn

```bash
yarn add @univerjs/data-validation @univerjs/sheets-data-validation @univerjs/sheets-data-validation-ui
```

#### bun

```bash
bun add @univerjs/data-validation @univerjs/sheets-data-validation @univerjs/sheets-data-validation-ui
```

### 使用

```typescript
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'
import { UniverDataValidationPlugin } from '@univerjs/data-validation' // [!code ++]
import { UniverSheetsDataValidationPlugin } from '@univerjs/sheets-data-validation' // [!code ++]
import { UniverSheetsDataValidationUIPlugin } from '@univerjs/sheets-data-validation-ui' // [!code ++]
import SheetsDataValidationZhTW from '@univerjs/sheets-data-validation-ui/locale/zh-TW' // [!code ++]

import '@univerjs/sheets-data-validation-ui/lib/index.css' // [!code ++]

import '@univerjs/sheets-data-validation/facade' // [!code ++]

const univer = new Univer({
  locale: LocaleType.ZH_TW,
  locales: {
    [LocaleType.ZH_TW]: mergeLocales(
      SheetsDataValidationZhTW, // [!code ++]
    ),
  },
})

univer.registerPlugin(UniverDataValidationPlugin) // [!code ++]
univer.registerPlugin(UniverSheetsDataValidationPlugin) // [!code ++]
univer.registerPlugin(UniverSheetsDataValidationUIPlugin) // [!code ++]
```

### 外掛與配置

```typescript
univer.registerPlugin(UniverSheetsDataValidationUIPlugin, {
  /**
   * 是否在下拉選單中顯示編輯按鈕
   * @default true
   */
  showEditOnDropdown: true,
  /**
   * 是否在下拉選單中顯示搜尋框
   * @default true
   */
  showSearchOnDropdown: true,
})
```

完整的配置項參考 [`IUniverSheetsDataValidationUIConfig`](https://github.com/dream-num/univer/blob/dev/packages/sheets-data-validation-ui/src/config/config.ts)。

## 行動裝置支援

先設定[行動版編輯器](https://docs.univer.ai/zh-TW/guides/sheets/getting-started/installation.md#mobile-support)。在本頁外掛模式的初始化程式碼中，將下列桌面版註冊替換為同一套件匯出的行動版外掛，並在**開啟文件前**完成。保留模型外掛、樣式、語言套件與 Facade 匯入，請勿同時註冊兩個版本。

| 套件                                    | 桌面版註冊                                | 行動版註冊                                      |
| ------------------------------------- | ------------------------------------ | ------------------------------------------ |
| `@univerjs/sheets-data-validation-ui` | `UniverSheetsDataValidationUIPlugin` | `UniverSheetsDataValidationMobileUIPlugin` |

## 預設模式

### 安裝

#### npm

```bash
npm install @univerjs/preset-sheets-data-validation
```

#### pnpm

```bash
pnpm add @univerjs/preset-sheets-data-validation
```

#### yarn

```bash
yarn add @univerjs/preset-sheets-data-validation
```

#### bun

```bash
bun add @univerjs/preset-sheets-data-validation
```

### 使用

```typescript
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreZhTW from '@univerjs/preset-sheets-core/locales/zh-TW'
import { UniverSheetsDataValidationPreset } from '@univerjs/preset-sheets-data-validation' // [!code ++]
import UniverPresetSheetsDataValidationZhTW from '@univerjs/preset-sheets-data-validation/locales/zh-TW' // [!code ++]
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'

import '@univerjs/preset-sheets-core/lib/index.css'
import '@univerjs/preset-sheets-data-validation/lib/index.css' // [!code ++]

const { univerAPI } = createUniver({
  locale: LocaleType.ZH_TW,
  locales: {
    [LocaleType.ZH_TW]: mergeLocales(
      UniverPresetSheetsCoreZhTW,
      UniverPresetSheetsDataValidationZhTW, // [!code ++]
    ),
  },
  presets: [
    UniverSheetsCorePreset(),
    UniverSheetsDataValidationPreset(), // [!code ++]
  ],
})
```

### 預設與配置

```typescript
UniverSheetsDataValidationPreset({
  /**
   * 是否在下拉選單中顯示編輯按鈕
   * @default true
   */
  showEditOnDropdown: true,
  /**
   * 是否在下拉選單中顯示搜尋框
   * @default true
   */
  showSearchOnDropdown: true,
})
```

完整的配置項參考 [`IUniverSheetsDataValidationPresetConfig`](https://github.com/dream-num/univer/tree/dev/presets/packages/preset-sheets-data-validation)。

## Facade API

完整 Facade API 型別定義，請檢視 [FacadeAPI](https://docs.univer.ai/zh-TW/reference/facade/univer.md)

### 引入

> [!INFO: 外掛模式提示]
> 僅外掛模式需要手動引入 Facade 套件。預設模式已內建對應的 Facade 套件，無需額外引入。

```typescript
import '@univerjs/sheets-data-validation/facade'
```

### 新增一個資料驗證規則

[`univerAPI.newDataValidation()`](https://docs.univer.ai/zh-TW/reference/facade/univer.md#newdatavalidation) 可以建立一個新的資料驗證構建器，返回一個 `FDataValidationBuilder` 例項，可以透過鏈式呼叫生成資料驗證規則。

以下是 [`FDataValidationBuilder`](https://docs.univer.ai/zh-TW/reference/facade/data-validation-builder.md) 上的一些成員方法：

| 方法                                | 描述                                            |
| --------------------------------- | --------------------------------------------- |
| build                             | 構建資料驗證規則                                      |
| requireCheckbox                   | 設定資料驗證規則，要求輸入為布林值；該值將呈現為核取方塊                  |
| requireDateAfter                  | 將資料驗證型別設定為 DATE，並配置驗證規則為在特定日期之後               |
| requireDateBefore                 | 將資料驗證型別設定為 DATE，並配置驗證規則為在特定日期之前               |
| requireDateBetween                | 將資料驗證型別設定為 DATE，並配置驗證規則為在特定日期範圍內              |
| requireDateEqualTo                | 將資料驗證型別設定為 DATE，並配置驗證規則為等於特定日期                |
| requireDateNotBetween             | 將資料驗證型別設定為 DATE，並配置驗證規則為不在特定日期範圍內             |
| requireDateOnOrAfter              | 將資料驗證型別設定為 DATE，並將驗證規則配置為特定日期或之後              |
| requireDateOnOrBefore             | 將資料驗證型別設定為 DATE，並將驗證規則配置為特定日期或之前              |
| requireFormulaSatisfied           | 設定資料驗證規則要求給定公式求值為 `true`                      |
| requireNumberBetween              | 設定資料驗證規則要求數字在兩個指定數字之間，或者是其中之一                 |
| requireNumberEqualTo              | 設定資料驗證規則要求數字等於給定值                             |
| requireNumberGreaterThan          | 設定資料驗證規則要求數字大於給定值                             |
| requireNumberGreaterThanOrEqualTo | 設定資料驗證規則要求數字大於或等於給定值                          |
| requireNumberLessThan             | 設定資料驗證規則要求數字小於給定值                             |
| requireNumberLessThanOrEqualTo    | 設定資料驗證規則要求數字小於或等於給定值                          |
| requireNumberNotBetween           | 設定資料驗證規則要求數字不在兩個指定數字之間，也不是其中之一                |
| requireNumberNotEqualTo           | 設定資料驗證規則要求數字不等於給定值                            |
| requireValueInList                | 設定資料驗證規則，要求使用者從特定值列表中輸入一個值。支援單選/多選，支援顯示/隱藏下拉框 |
| requireValueInRange               | 設定資料驗證規則，要求使用者輸入特定範圍內的值。支援單選/多選，支援顯示/隱藏下拉框    |
| setOptions                        | 設定資料驗證規則的選項                                   |

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()

// 建立一個新的資料驗證規則，要求 A1:B10 範圍內的數字在 1 到 10 之間
const fRange = fWorksheet.getRange('A1:B10')
const rule = univerAPI.newDataValidation()
  .requireNumberBetween(1, 10)
  .setOptions({
    allowBlank: true,
    showErrorMessage: true,
    error: 'Please enter a number between 1 and 10',
  })
  .build()
fRange.setDataValidation(rule)
```

### 清除 Range 的資料驗證規則

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()

// 清除 A1:B10 範圍內的資料驗證規則
const fRange = fWorksheet.getRange('A1:B10')
fRange.setDataValidation(null)
```

### 獲取 Range/Worksheet 的資料驗證規則

返回的資料驗證規則物件是一個 `FDataValidation` 例項，可以透過該例項獲取驗證規則的條件、選項等。

以下是 [`FDataValidation`](https://docs.univer.ai/zh-TW/reference/facade/data-validation.md) 上的一些成員方法：

| 方法                | 描述                                       |
| ----------------- | ---------------------------------------- |
| copy              | 使用當前規則物件建立一個新的 FDataValidationBuilder 實例 |
| getCriteriaType   | 獲取資料驗證規則的型別                              |
| getCriteriaValues | 獲取資料驗證規則的條件值                             |
| getHelpText       | 獲取幫助文字資訊，用於為使用者提供指導和支援                   |
| getRanges         | 獲取資料驗證規則的應用範圍                            |
| setCriteria       | 設定資料驗證規則的條件值                             |
| setOptions        | 設定資料驗證規則的選項                              |
| setRanges         | 設定資料驗證規則的應用範圍                            |
| delete            | 從工作表中刪除資料驗證規則                            |

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()

// 獲取當前工作表的所有資料驗證規則
const rulesOfSheet = fWorksheet.getDataValidations()

// 透過規則 ID 獲取資料驗證規則
const ruleById = fWorksheet.getDataValidation(rulesOfSheet[0]?.rule?.uid)

const fRange = fWorksheet.getRange('A1:B10')

// 獲取當前範圍的第一個資料驗證規則
const ruleOfRange = fRange.getDataValidation()
ruleOfRange?.getCriteriaValues()

// 獲取當前範圍的所有資料驗證規則
const rulesOfRange = fRange.getDataValidations()
```

### 更新/刪除資料驗證

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()

// 建立一個新的資料驗證規則，要求 A1:B10 範圍內的數字等於 20
const fRange = fWorksheet.getRange('A1:B10')
const rule = univerAPI.newDataValidation()
  .requireNumberEqualTo(20)
  .build()
fRange.setDataValidation(rule)

const newRuleRange = fWorksheet.getRange('C1:D10')

// 3 秒後更新規則
setTimeout(() => {
  fRange.getDataValidation()
    // 更改新的範圍 C1:D10
    .setRanges([newRuleRange])
    // 更改新的條件，要求數字在 1 到 10 之間
    .setCriteria(
      univerAPI.Enum.DataValidationType.DECIMAL,
      [univerAPI.Enum.DataValidationOperator.BETWEEN, '1', '10'],
    )
    // 更改驗證選項，當輸入不符合條件時停止輸入並顯示錯誤訊息
    .setOptions({
      allowBlank: true,
      showErrorMessage: true,
      error: 'Please enter a valid value',
      errorStyle: univerAPI.Enum.DataValidationErrorStyle.STOP,
    })
}, 3000)

// 6 秒後刪除該規則
setTimeout(() => {
  newRuleRange.getDataValidation().delete()
}, 6000)
```

### 獲取驗證錯誤

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()

// 獲取當前工作簿的所有資料驗證錯誤
const workbookErrors = await fWorkbook.getAllDataValidationErrorAsync()
console.log('workbookErrors:', workbookErrors)

// 獲取當前工作表的所有資料驗證錯誤
const worksheetErrors = await fWorksheet.getAllDataValidationErrorAsync()
console.log('worksheetErrors:', worksheetErrors)

// 獲取當前範圍的資料驗證錯誤
const fRange = fWorksheet.getRange('A1:B10')
const rangeErrors = await fRange.getDataValidationErrorAsync()
console.log('rangeErrors:', rangeErrors)
```

每個錯誤物件包含以下欄位：

* `sheetName`：發生錯誤的工作表名稱
* `row`：觸發錯誤的儲存格列索引
* `column`：觸發錯誤的儲存格欄索引
* `ruleId`：觸發錯誤的規則 ID
* `inputValue`：觸發錯誤的輸入值
* `rule`：規則內容快照

### 查詢校驗狀態

校驗狀態是 `DataValidationStatus` 的列舉值，包括：

* `valid`：儲存格值通過驗證
* `invalid`：儲存格值未通過驗證
* `validating`：儲存格正在驗證中

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()

// 獲取當前工作簿的資料驗證校驗狀態
fWorkbook.getValidatorStatus().then((status) => {
})

// 獲取當前工作表的資料驗證校驗狀態
fWorksheet.getValidatorStatusAsync().then((status) => {
})

// 獲取當前範圍的資料驗證校驗狀態
const fRange = fWorksheet.getRange('A1:B10')
fRange.getValidatorStatus().then((status) => {
})
```

### 事件監聽

完整事件型別定義，請檢視 [Events](https://docs.univer.ai/zh-TW/reference/facade/events.md)。

資料驗證模組提供了一系列事件用於監聽驗證規則的新增、更新、刪除和驗證狀態變更。所有事件都可以透過 `univerAPI.addEvent()` 進行監聽。

#### 驗證規則變更事件

`univerAPI.Event.SheetDataValidationChanged`: 驗證規則變更後觸發

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.SheetDataValidationChanged, (params) => {
  const { origin, worksheet, workbook, changeType, oldRule, rule } = params
})

// 移除事件監聽器，使用 `disposable.dispose()`
```

`univerAPI.Event.BeforeSheetDataValidationAdd`: 新增驗證規則前觸發

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationAdd, (params) => {
  const { worksheet, workbook, rule } = params

  // 取消新增驗證規則操作
  params.cancel = true
})

// 移除事件監聽器，使用 `disposable.dispose()`
```

`univerAPI.Event.BeforeSheetDataValidationDelete`: 刪除驗證規則前觸發

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationDelete, (params) => {
  const { worksheet, workbook, ruleId, rule } = params

  // 取消刪除驗證規則操作
  params.cancel = true
})

// 移除事件監聽器，使用 `disposable.dispose()`
```

`univerAPI.Event.BeforeSheetDataValidationDeleteAll`: 刪除所有驗證規則前觸發

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationDeleteAll, (params) => {
  const { worksheet, workbook, rules } = params

  // 取消刪除所有驗證規則操作
  params.cancel = true
})

// 移除事件監聽器，使用 `disposable.dispose()`
```

#### 驗證規則更新事件

`univerAPI.Event.BeforeSheetDataValidationCriteriaUpdate`: 更新驗證規則條件前觸發

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationCriteriaUpdate, (params) => {
  const { worksheet, workbook, ruleId, rule, newCriteria } = params

  // 取消更新驗證規則條件操作
  params.cancel = true
})

// 移除事件監聽器，使用 `disposable.dispose()`
```

`univerAPI.Event.BeforeSheetDataValidationRangeUpdate`: 更新驗證規則範圍前觸發

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationRangeUpdate, (params) => {
  const { worksheet, workbook, ruleId, rule, newRanges } = params

  // 取消更新驗證規則範圍操作
  params.cancel = true
})

// 移除事件監聽器，使用 `disposable.dispose()`
```

`univerAPI.Event.BeforeSheetDataValidationOptionsUpdate`: 更新驗證規則選項前觸發

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationOptionsUpdate, (params) => {
  const { worksheet, workbook, ruleId, rule, newOptions } = params

  // 取消更新驗證規則選項操作
  params.cancel = true
})

// 移除事件監聽器，使用 `disposable.dispose()`
```

#### 驗證狀態事件

`univerAPI.Event.SheetDataValidatorStatusChanged`: 單元格驗證狀態變更時觸發

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.SheetDataValidatorStatusChanged, (params) => {
  const { worksheet, workbook, row, column, status, rule } = params
})

// 移除事件監聽器，使用 `disposable.dispose()`
```

每個事件都包含以下通用參數：

* `workbook`: 當前工作簿例項
* `worksheet`: 當前工作表例項

特殊參數：

* `rule`: 相關的驗證規則物件
* `ruleId`: 驗證規則的唯一識別符號
* `status`: 驗證狀態（僅在 `SheetDataValidatorStatusChanged` 事件中）
* `newCriteria`: 新的驗證條件（僅在 `BeforeSheetDataValidationCriteriaUpdate` 事件中）
* `newRanges`: 新的驗證範圍（僅在 `BeforeSheetDataValidationRangeUpdate` 事件中）
* `newOptions`: 新的驗證選項（僅在 `BeforeSheetDataValidationOptionsUpdate` 事件中）

所有 `Before` 字首的事件回撥函式都可以使用 `params.cancel = true` 來阻止對應的操作。

### 錯誤樣式

`errorStyle` 選項控制輸入無效資料時的行為。它是 `DataValidationErrorStyle` 的列舉值，包括：

* `STOP`：阻止使用者輸入無效資料
* `WARNING`：允許使用者輸入無效資料，但顯示警告
* `INFO`：允許使用者輸入無效資料，但顯示資訊提示

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B10')

const rule = univerAPI.newDataValidation()
  .requireNumberBetween(1, 10)
  .setOptions({
    allowBlank: true,
    showErrorMessage: true,
    error: '請輸入 1 到 10 之間的數字',
    errorStyle: univerAPI.Enum.DataValidationErrorStyle.STOP,
  })
  .build()
fRange.setDataValidation(rule)
```

### 變更列表型驗證的渲染模式

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B10')

fRange.getDataValidation()?.setOptions({
  // support TEXT, ARROW, CUSTOM
  // default is `CUSTOM`
  renderMode: univerAPI.Enum.DataValidationRenderMode.TEXT,
})
```
