diff --git a/examples/app_data_validation.rs b/examples/app_data_validation.rs
new file mode 100644
index 00000000..ec7384c9
--- /dev/null
+++ b/examples/app_data_validation.rs
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of how to add data validation and dropdown lists using the
+//! rust_xlsxwriter library.
+//!
+//! Data validation is a feature of Excel which allows you to restrict the data
+//! that a user enters in a cell and to display help and warning messages. It
+//! also allows you to restrict input to values in a drop down list.
+
+use rust_xlsxwriter::{
+ DataValidation, DataValidationErrorStyle, DataValidationRule, ExcelDateTime, Format,
+ FormatAlign, FormatBorder, Formula, Workbook, XlsxError,
+};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+
+ // Add a worksheet to the workbook.
+ let worksheet = workbook.add_worksheet();
+
+ // Add a format for the header cells.
+ let header_format = Format::new()
+ .set_background_color("C6EFCE")
+ .set_border(FormatBorder::Thin)
+ .set_bold()
+ .set_indent(1)
+ .set_text_wrap()
+ .set_align(FormatAlign::VerticalCenter);
+
+ // Set up layout of the worksheet.
+ worksheet.set_column_width(0, 68)?;
+ worksheet.set_column_width(1, 15)?;
+ worksheet.set_column_width(3, 15)?;
+ worksheet.set_row_height(0, 36)?;
+
+ // Write the header cells and some data that will be used in the examples.
+ let heading1 = "Some examples of data validations";
+ let heading2 = "Enter values in this column";
+ let heading3 = "Sample Data";
+
+ worksheet.write_with_format(0, 0, heading1, &header_format)?;
+ worksheet.write_with_format(0, 1, heading2, &header_format)?;
+ worksheet.write_with_format(0, 3, heading3, &header_format)?;
+
+ worksheet.write(2, 3, "Integers")?;
+ worksheet.write(2, 4, 1)?;
+ worksheet.write(2, 5, 10)?;
+
+ worksheet.write_row(3, 3, ["List data", "open", "high", "close"])?;
+
+ worksheet.write(4, 3, "Formula")?;
+ worksheet.write(4, 4, Formula::new("=AND(F5=50,G5=60)"))?;
+ worksheet.write(4, 5, 50)?;
+ worksheet.write(4, 6, 60)?;
+
+ // -----------------------------------------------------------------------
+ // Example 1. Limiting input to an integer in a fixed range.
+ // -----------------------------------------------------------------------
+ let text = "Enter an integer between 1 and 10";
+ worksheet.write(2, 0, text)?;
+
+ let data_validation =
+ DataValidation::new().allow_whole_number(DataValidationRule::Between(1, 10));
+
+ worksheet.add_data_validation(2, 1, 2, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 2. Limiting input to an integer outside a fixed range.
+ // -----------------------------------------------------------------------
+ let text = "Enter an integer that is not between 1 and 10 (using cell references)";
+ worksheet.write(4, 0, text)?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number_formula(DataValidationRule::NotBetween("=E3".into(), "=F3".into()));
+
+ worksheet.add_data_validation(4, 1, 4, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 3. Limiting input to an integer greater than a fixed value.
+ // -----------------------------------------------------------------------
+ let text = "Enter an integer greater than 0";
+ worksheet.write(6, 0, text)?;
+
+ let data_validation =
+ DataValidation::new().allow_whole_number(DataValidationRule::GreaterThan(0));
+
+ worksheet.add_data_validation(6, 1, 6, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 4. Limiting input to an integer less than a fixed value.
+ // -----------------------------------------------------------------------
+ let text = "Enter an integer less than 10";
+ worksheet.write(8, 0, text)?;
+
+ let data_validation =
+ DataValidation::new().allow_whole_number(DataValidationRule::LessThan(10));
+
+ worksheet.add_data_validation(8, 1, 8, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 5. Limiting input to a decimal in a fixed range.
+ // -----------------------------------------------------------------------
+ let text = "Enter a decimal between 0.1 and 0.5";
+ worksheet.write(10, 0, text)?;
+
+ let data_validation =
+ DataValidation::new().allow_decimal_number(DataValidationRule::Between(0.1, 0.5));
+
+ worksheet.add_data_validation(10, 1, 10, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 6. Limiting input to a value in a dropdown list.
+ // -----------------------------------------------------------------------
+ let text = "Select a value from a drop down list";
+ worksheet.write(12, 0, text)?;
+
+ let data_validation = DataValidation::new().allow_list_strings(&["open", "high", "close"])?;
+
+ worksheet.add_data_validation(12, 1, 12, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 7. Limiting input to a value in a dropdown list.
+ // -----------------------------------------------------------------------
+ let text = "Select a value from a drop down list (using a cell range)";
+ worksheet.write(14, 0, text)?;
+
+ let data_validation = DataValidation::new().allow_list_formula("=$E$4:$G$4".into());
+
+ worksheet.add_data_validation(14, 1, 14, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 8. Limiting input to a date in a fixed range.
+ // -----------------------------------------------------------------------
+ let text = "Enter a date between 1/1/2025 and 12/12/2025";
+ worksheet.write(16, 0, text)?;
+
+ let data_validation = DataValidation::new().allow_date(DataValidationRule::Between(
+ ExcelDateTime::parse_from_str("2025-01-01")?,
+ ExcelDateTime::parse_from_str("2025-12-12")?,
+ ));
+
+ worksheet.add_data_validation(16, 1, 16, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 9. Limiting input to a time in a fixed range.
+ // -----------------------------------------------------------------------
+ let text = "Enter a time between 6:00 and 12:00";
+ worksheet.write(18, 0, text)?;
+
+ let data_validation = DataValidation::new().allow_time(DataValidationRule::Between(
+ ExcelDateTime::parse_from_str("6:00")?,
+ ExcelDateTime::parse_from_str("12:00")?,
+ ));
+
+ worksheet.add_data_validation(18, 1, 18, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 10. Limiting input to a string greater than a fixed length.
+ // -----------------------------------------------------------------------
+ let text = "Enter a string longer than 3 characters";
+ worksheet.write(20, 0, text)?;
+
+ let data_validation =
+ DataValidation::new().allow_text_length(DataValidationRule::GreaterThan(3));
+
+ worksheet.add_data_validation(20, 1, 20, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 11. Limiting input based on a formula.
+ // -----------------------------------------------------------------------
+ let text = "Enter a value if the following is true '=AND(F5=50,G5=60)'";
+ worksheet.write(22, 0, text)?;
+
+ let data_validation = DataValidation::new().allow_custom("=AND(F5=50,G5=60)".into());
+
+ worksheet.add_data_validation(22, 1, 22, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 12. Displaying and modifying data validation messages.
+ // -----------------------------------------------------------------------
+ let text = "Displays a message when you select the cell";
+ worksheet.write(24, 0, text)?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number(DataValidationRule::Between(1, 100))
+ .set_input_title("Enter an integer:")
+ .set_input_message("between 1 and 100");
+
+ worksheet.add_data_validation(24, 1, 24, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 13. Displaying and modifying data validation messages.
+ // -----------------------------------------------------------------------
+ let text = "Display a custom error message when integer isn't between 1 and 100";
+ worksheet.write(26, 0, text)?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number(DataValidationRule::Between(1, 100))
+ .set_input_title("Enter an integer:")
+ .set_input_message("between 1 and 100")
+ .set_error_title("Input value is not valid!")
+ .set_error_message("It should be an integer between 1 and 100");
+
+ worksheet.add_data_validation(26, 1, 26, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Example 14. Displaying and modifying data validation messages.
+ // -----------------------------------------------------------------------
+ let text = "Display a custom info message when integer isn't between 1 and 100";
+ worksheet.write(28, 0, text)?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number(DataValidationRule::Between(1, 100))
+ .set_input_title("Enter an integer:")
+ .set_input_message("between 1 and 100")
+ .set_error_title("Input value is not valid!")
+ .set_error_message("It should be an integer between 1 and 100")
+ .set_error_style(DataValidationErrorStyle::Information);
+
+ worksheet.add_data_validation(28, 1, 28, 1, &data_validation)?;
+
+ // -----------------------------------------------------------------------
+ // Save and close the file.
+ // -----------------------------------------------------------------------
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_custom.rs b/examples/doc_data_validation_allow_custom.rs
new file mode 100644
index 00000000..76a5d2ed
--- /dev/null
+++ b/examples/doc_data_validation_allow_custom.rs
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts input to text/strings that are uppercase.
+
+use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter uppercase string in D2:")?;
+
+ let data_validation =
+ DataValidation::new().allow_custom("=AND(ISTEXT(D2), EXACT(D2, UPPER(D2)))".into());
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_date.rs b/examples/doc_data_validation_allow_date.rs
new file mode 100644
index 00000000..13a16fca
--- /dev/null
+++ b/examples/doc_data_validation_allow_date.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts input to date values in a fixed range.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, ExcelDateTime, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation = DataValidation::new().allow_date(DataValidationRule::Between(
+ ExcelDateTime::parse_from_str("2025-01-01")?,
+ ExcelDateTime::parse_from_str("2025-12-12")?,
+ ));
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_decimal_number.rs b/examples/doc_data_validation_allow_decimal_number.rs
new file mode 100644
index 00000000..9b565aca
--- /dev/null
+++ b/examples/doc_data_validation_allow_decimal_number.rs
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts input to floating point values in a fixed range.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation =
+ DataValidation::new().allow_decimal_number(DataValidationRule::Between(-9.9, 9.9));
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_decimal_number_formula.rs b/examples/doc_data_validation_allow_decimal_number_formula.rs
new file mode 100644
index 00000000..7bd2c8db
--- /dev/null
+++ b/examples/doc_data_validation_allow_decimal_number_formula.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts input to floating point values based on a value from another cell.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(0, 0, "Upper limit:")?;
+ worksheet.write(0, 3, 99.9)?;
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation = DataValidation::new()
+ .allow_decimal_number_formula(DataValidationRule::LessThanOrEqualTo("=D1".into()));
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_list_formula.rs b/examples/doc_data_validation_allow_list_formula.rs
new file mode 100644
index 00000000..c3dcf861
--- /dev/null
+++ b/examples/doc_data_validation_allow_list_formula.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts users to a selection of values from a dropdown list. The list data
+//! is provided from a cell range.
+
+use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Select value in cell D2:")?;
+
+ // Write the string list data to some cells.
+ let string_list = ["Pass", "Fail", "Incomplete"];
+ worksheet.write_column(1, 5, string_list)?;
+
+ let data_validation = DataValidation::new().allow_list_formula("F2:F4".into());
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_list_strings.rs b/examples/doc_data_validation_allow_list_strings.rs
new file mode 100644
index 00000000..8a259a36
--- /dev/null
+++ b/examples/doc_data_validation_allow_list_strings.rs
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts users to a selection of values from a dropdown list.
+
+use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Select value in cell D2:")?;
+
+ let data_validation =
+ DataValidation::new().allow_list_strings(&["Pass", "Fail", "Incomplete"])?;
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_list_strings2.rs b/examples/doc_data_validation_allow_list_strings2.rs
new file mode 100644
index 00000000..cd67aac4
--- /dev/null
+++ b/examples/doc_data_validation_allow_list_strings2.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts users to a selection of values from a dropdown list. This example
+//! shows how to pre-populate a default choice.
+
+use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Select value in cell D2:")?;
+
+ let data_validation =
+ DataValidation::new().allow_list_strings(&["Pass", "Fail", "Incomplete"])?;
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Add a default string to the cell with the data validation
+ // to pre-populate a default choice.
+ worksheet.write(1, 3, "Pass")?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_text_length.rs b/examples/doc_data_validation_allow_text_length.rs
new file mode 100644
index 00000000..b6217403
--- /dev/null
+++ b/examples/doc_data_validation_allow_text_length.rs
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts input to strings whose lengths is in a fixed range.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation =
+ DataValidation::new().allow_text_length(DataValidationRule::Between(4, 8));
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_time.rs b/examples/doc_data_validation_allow_time.rs
new file mode 100644
index 00000000..71a903ab
--- /dev/null
+++ b/examples/doc_data_validation_allow_time.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts input to time values in a fixed range.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, ExcelDateTime, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation = DataValidation::new().allow_time(DataValidationRule::Between(
+ ExcelDateTime::parse_from_str("6:00")?,
+ ExcelDateTime::parse_from_str("12:00")?,
+ ));
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_whole_number.rs b/examples/doc_data_validation_allow_whole_number.rs
new file mode 100644
index 00000000..7cc37933
--- /dev/null
+++ b/examples/doc_data_validation_allow_whole_number.rs
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts input to integer values in a fixed range.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation =
+ DataValidation::new().allow_whole_number(DataValidationRule::Between(1, 10));
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_whole_number_formula.rs b/examples/doc_data_validation_allow_whole_number_formula.rs
new file mode 100644
index 00000000..ee7d4dea
--- /dev/null
+++ b/examples/doc_data_validation_allow_whole_number_formula.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts input to integer values based on a value from another cell.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(0, 0, "Upper limit:")?;
+ worksheet.write(0, 3, 10)?;
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number_formula(DataValidationRule::LessThanOrEqualTo("=D1".into()));
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_allow_whole_number_formula2.rs b/examples/doc_data_validation_allow_whole_number_formula2.rs
new file mode 100644
index 00000000..1f32c505
--- /dev/null
+++ b/examples/doc_data_validation_allow_whole_number_formula2.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! restricts input to integer values based on a value from another cell.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Formula, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(0, 0, "Upper limit:")?;
+ worksheet.write(0, 3, 10)?;
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number_formula(DataValidationRule::LessThanOrEqualTo(Formula::new("=D1")));
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_intro1.rs b/examples/doc_data_validation_intro1.rs
new file mode 100644
index 00000000..d3b0afbc
--- /dev/null
+++ b/examples/doc_data_validation_intro1.rs
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! uses an input message to explain to the user what type of input is required.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter rating in cell D2:")?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number(DataValidationRule::Between(1, 5))
+ .set_input_title("Enter a star rating!")
+ .set_input_message("Enter rating 1-5.\nWhole numbers only.")
+ .set_error_title("Value outside allowed range")
+ .set_error_message("The input value must be an integer in the range 1-5.");
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_set_error_message.rs b/examples/doc_data_validation_set_error_message.rs
new file mode 100644
index 00000000..9d2bd7e0
--- /dev/null
+++ b/examples/doc_data_validation_set_error_message.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! shows a custom error message.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number(DataValidationRule::Between(1, 10))
+ .set_error_title("Value outside allowed range")
+ .set_error_message("The input value must be an integer in the range 1-10.");
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_set_error_title.rs b/examples/doc_data_validation_set_error_title.rs
new file mode 100644
index 00000000..fab8853f
--- /dev/null
+++ b/examples/doc_data_validation_set_error_title.rs
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! shows a custom error title.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter value in cell D2:")?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number(DataValidationRule::Between(1, 10))
+ .set_error_title("Danger, Will Robinson!");
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/examples/doc_data_validation_set_input_message.rs b/examples/doc_data_validation_set_input_message.rs
new file mode 100644
index 00000000..61c90e5f
--- /dev/null
+++ b/examples/doc_data_validation_set_input_message.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
+
+//! Example of adding a data validation to a worksheet cell. This validation
+//! uses an input message to explain to the user what type of input is required.
+
+use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+
+fn main() -> Result<(), XlsxError> {
+ // Create a new Excel file object.
+ let mut workbook = Workbook::new();
+ let worksheet = workbook.add_worksheet();
+
+ worksheet.write(1, 0, "Enter rating in cell D2:")?;
+
+ let data_validation = DataValidation::new()
+ .allow_whole_number(DataValidationRule::Between(1, 5))
+ .set_input_title("Enter a star rating!")
+ .set_input_message("Enter rating 1-5.\nWhole numbers only.");
+
+ worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+
+ // Save the file.
+ workbook.save("data_validation.xlsx")?;
+
+ Ok(())
+}
diff --git a/src/data_validation.rs b/src/data_validation.rs
index b3f616a5..b21e229b 100644
--- a/src/data_validation.rs
+++ b/src/data_validation.rs
@@ -4,10 +4,6 @@
//
// Copyright 2022-2024, John McNamara, jmcnamara@cpan.org
-//! # Working with Data Validation
-//!
-//! TODO
-
#![warn(missing_docs)]
mod tests;
@@ -22,9 +18,162 @@ use std::fmt;
// DataValidation
// -----------------------------------------------------------------------
-/// The `DataValidation` struct represents a Cell conditional format.
+/// The `DataValidation` struct represents a cell Data Validation.
+///
+/// `DataValidation` is used in conjunction with the
+/// [`Worksheet::add_data_validation()`](crate::Worksheet::add_data_validation)
+/// method.
+///
+/// # Working with Data Validation
+///
+/// Data validation is a feature of Excel that allows you to restrict the data
+/// that a user enters in a cell and to display associated help and warning
+/// messages. It also allows you to restrict input to values in a dropdown list.
+///
+/// A typical use case might be to restrict data in a cell to integer values in
+/// a certain range, to provide a help message to indicate the required value,
+/// and to issue a warning if the input data doesn't meet the stated criteria.
+///
+///
+///
+/// This example was created with the following code:
+///
+/// ```
+/// # // This code is available in examples/doc_data_validation_intro1.rs
+/// #
+/// use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+///
+/// fn main() -> Result<(), XlsxError> {
+/// // Create a new Excel file object.
+/// let mut workbook = Workbook::new();
+/// let worksheet = workbook.add_worksheet();
+///
+/// worksheet.write(1, 0, "Enter rating in cell D2:")?;
+///
+/// let data_validation = DataValidation::new()
+/// .allow_whole_number(DataValidationRule::Between(1, 5))
+/// .set_input_title("Enter a star rating!")
+/// .set_input_message("Enter rating 1-5.\nWhole numbers only.")
+/// .set_error_title("Value outside allowed range")
+/// .set_error_message("The input value must be an integer in the range 1-5.");
+///
+/// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+///
+/// // Save the file.
+/// workbook.save("data_validation.xlsx")?;
+///
+/// Ok(())
+/// }
+/// ```
+///
+/// Another common data validation task is to limit input to values on a
+/// dropdown list.
+///
+///
+///
+/// This example was created with the following code:
+///
+/// ```
+/// # // This code is available in examples/doc_data_validation_allow_list_strings.rs
+/// #
+/// use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+///
+/// fn main() -> Result<(), XlsxError> {
+/// // Create a new Excel file object.
+/// let mut workbook = Workbook::new();
+/// let worksheet = workbook.add_worksheet();
+///
+/// worksheet.write(1, 0, "Select value in cell D2:")?;
+///
+/// let data_validation =
+/// DataValidation::new().allow_list_strings(&["Pass", "Fail", "Incomplete"])?;
+///
+/// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+///
+/// // Save the file.
+/// workbook.save("data_validation.xlsx")?;
+///
+/// Ok(())
+/// }
+/// ```
+///
+/// For more information and examples see the API documentation below.
+///
+///
+/// ## Using cell references in Data Validations
+///
+/// Excel allows the values for data validation to be either a "literal" number,
+/// date or time value or a cell reference such as `=D1`. In the `DataValidation`
+/// interfaces these are represented using a [`Formula`] value, like this:
+///
+/// ```
+/// # // This code is available in examples/doc_data_validation_allow_whole_number_formula2.rs
+/// #
+/// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Formula, Workbook, XlsxError};
+/// #
+/// # fn main() -> Result<(), XlsxError> {
+/// # // Create a new Excel file object.
+/// # let mut workbook = Workbook::new();
+/// # let worksheet = workbook.add_worksheet();
+/// #
+/// # worksheet.write(0, 0, "Upper limit:")?;
+/// # worksheet.write(0, 3, 10)?;
+/// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+/// #
+/// let data_validation = DataValidation::new()
+/// .allow_whole_number_formula(
+/// DataValidationRule::LessThanOrEqualTo(Formula::new("=D1")));
+/// #
+/// # worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+/// #
+/// # // Save the file.
+/// # workbook.save("data_validation.xlsx")?;
+/// #
+/// # Ok(())
+/// # }
+/// ```
+/// In Excel this creates the following data validation:
+///
+///
+///
+/// As a syntactic shorthand you can also use `into()` like this:
///
-/// TODO
+/// ```
+/// # // This code is available in examples/doc_data_validation_allow_whole_number_formula.rs
+/// #
+/// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+/// #
+/// # fn main() -> Result<(), XlsxError> {
+/// # // Create a new Excel file object.
+/// # let mut workbook = Workbook::new();
+/// # let worksheet = workbook.add_worksheet();
+/// #
+/// # worksheet.write(0, 0, "Upper limit:")?;
+/// # worksheet.write(0, 3, 10)?;
+/// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+/// #
+/// let data_validation = DataValidation::new()
+/// .allow_whole_number_formula(DataValidationRule::LessThanOrEqualTo("=D1".into()));
+/// #
+/// # worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+/// #
+/// # // Save the file.
+/// # workbook.save("data_validation.xlsx")?;
+/// #
+/// # Ok(())
+/// # }
+/// ```
+///
+/// APIs that use [`Formula`] can also take Excel formulas, where that makes
+/// sense.
+///
+/// **Note**: the contents of the `Formula` aren't validated by
+/// `rust_xlsxwriter` so you should take care to ensure that the ranges or
+/// formulas are valid in Excel if you are using anything other than a simple
+/// range.
///
#[derive(Clone)]
pub struct DataValidation {
@@ -42,7 +191,12 @@ pub struct DataValidation {
}
impl DataValidation {
- /// Create a new Cell conditional format struct.
+ /// Create a new cell Data Validation struct.
+ ///
+ /// The default type of a new data validation is equivalent to Excel's "Any"
+ /// data validation. Refer to the `allow_TYPE()` functions below to
+ /// constrain the data validation to defined types and apply rules.
+ ///
#[allow(clippy::new_without_default)]
pub fn new() -> DataValidation {
DataValidation {
@@ -60,19 +214,56 @@ impl DataValidation {
}
}
- /// Set the TODO
+ /// Set a data validation to limit input to integers using defined rules.
///
- /// TODO
+ /// Set a data validation rule to restrict cell input to integers based on
+ /// [`DataValidationRule`] rules such as "between" or "less than". Excel
+ /// refers to this data validation type as "Whole number" but it equates to
+ /// any Rust type that can convert [`Into`] a [`i32`] (`i64/u64` values
+ /// aren't supported by Excel).
///
- pub fn allow_any_value(mut self) -> DataValidation {
- self.rule = DataValidationRuleInternal::EqualTo(String::new());
- self.validation_type = DataValidationType::Any;
- self
- }
-
- /// Set the TODO
+ /// # Parameters
+ ///
+ /// * `rule` - A [`DataValidationRule`] with [`i32`] values.
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts input to integer values in a fixed range.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_whole_number.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+ /// #
+ /// let data_validation =
+ /// DataValidation::new().allow_whole_number(DataValidationRule::Between(1, 10));
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
///
- /// TODO
+ /// Output file:
+ ///
+ ///
+ ///
+ /// The Excel Data Validation dialog for this file should look something like this:
+ ///
+ ///
///
pub fn allow_whole_number(mut self, rule: DataValidationRule) -> DataValidation {
self.rule = rule.to_internal_rule();
@@ -80,9 +271,59 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation to limit input to integers using defined rules and
+ /// a cell reference.
+ ///
+ /// Set a data validation rule to restrict cell input to integers based on
+ /// [`DataValidationRule`] rules such as "between" or "less than". Excel
+ /// refers to this data validation type as "Whole number". The values used
+ /// for the rules should be a cell reference represented by a [`Formula`],
+ /// see [Using cell references in Data Validations] and the example below.
+ ///
+ /// # Parameters
+ ///
+ /// * `rule` - A [`DataValidationRule`] with cell references using
+ /// [`Formula`] values. See [Using cell references in Data Validations].
+ ///
+ /// [Using cell references in Data Validations]:
+ /// #using-cell-references-in-data-validations
///
- /// TODO
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts input to integer values based on a value from another cell.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_whole_number_formula.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(0, 0, "Upper limit:")?;
+ /// # worksheet.write(0, 3, 10)?;
+ /// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+ /// #
+ /// let data_validation = DataValidation::new()
+ /// .allow_whole_number_formula(DataValidationRule::LessThanOrEqualTo("=D1".into()));
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// The Excel Data Validation dialog for the output file should look
+ /// something like this:
+ ///
+ ///
///
pub fn allow_whole_number_formula(
mut self,
@@ -93,9 +334,56 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation to limit input to floating point numbers using
+ /// defined rules.
+ ///
+ /// Set a data validation rule to restrict cell input to floating point
+ /// numbers based on [`DataValidationRule`] rules such as "between" or "less
+ /// than". Excel refers to this data validation type as "Decimal" but it
+ /// equates to the Rust type [`f64`].
///
- /// TODO
+ /// # Parameters
+ ///
+ /// * `rule` - A [`DataValidationRule`] with [`f64`] values.
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts input to floating point values in a fixed range.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_decimal_number.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+ /// #
+ /// let data_validation =
+ /// DataValidation::new().allow_decimal_number(DataValidationRule::Between(-9.9, 9.9));
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// Output file:
+ ///
+ ///
+ ///
+ /// The Excel Data Validation dialog for this file should look something like this:
+ ///
+ ///
///
pub fn allow_decimal_number(mut self, rule: DataValidationRule) -> DataValidation {
self.rule = rule.to_internal_rule();
@@ -103,9 +391,60 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation to limit input to floating point numbers using
+ /// defined rules and a cell reference.
+ ///
+ /// Set a data validation rule to restrict cell input to floating point
+ /// numbers based on [`DataValidationRule`] rules such as "between" or "less
+ /// than". Excel refers to this data validation type as "Decimal". The
+ /// values used for the rules should be a cell reference represented by a
+ /// [`Formula`], see [Using cell references in Data Validations] and the
+ /// example below.
+ ///
+ /// # Parameters
+ ///
+ /// * `rule` - A [`DataValidationRule`] with cell references using
+ /// [`Formula`] values. See [Using cell references in Data Validations].
+ ///
+ /// [Using cell references in Data Validations]:
+ /// #using-cell-references-in-data-validations
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts input to floating point values based on a value from another
+ /// cell.
///
- /// TODO
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_decimal_number_formula.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(0, 0, "Upper limit:")?;
+ /// # worksheet.write(0, 3, 99.9)?;
+ /// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+ /// #
+ /// let data_validation = DataValidation::new()
+ /// .allow_decimal_number_formula(DataValidationRule::LessThanOrEqualTo("=D1".into()));
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// The Excel Data Validation dialog for the output file should look something like this:
+ ///
+ ///
///
pub fn allow_decimal_number_formula(
mut self,
@@ -116,12 +455,98 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation rule to restrict cell input to a selection of
+ /// strings via a dropdown menu.
+ ///
+ /// **Note**: Excel has a 255 character limit to the the string used to
+ /// store the comma-separated list of strings, including the commas. An
+ /// example of the comma-separated string is shown in the Excel Data
+ /// Validation dialog below. This limit makes it unsuitable for long lists
+ /// such as a list of provinces or states. For longer lists it is better to
+ /// place the string values somewhere in the Excel workbook and refer to
+ /// them using a range formula via the
+ /// [`DataValidation::allow_list_formula()`] method shown below.
///
- /// TODO
+ /// # Parameters
+ ///
+ /// * `list` - A list of string like objects.
///
/// # Errors
///
+ /// * [`XlsxError::DataValidationError`] - The length of the accumulated
+ /// comma-separated list of strings, including commas, exceeds Excel's
+ /// limit of 255 characters, see the note above.
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts users to a selection of values from a dropdown list.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_list_strings.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Select value in cell D2:")?;
+ /// #
+ /// let data_validation =
+ /// DataValidation::new().allow_list_strings(&["Pass", "Fail", "Incomplete"])?;
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// Output file:
+ ///
+ ///
+ ///
+ /// The Excel Data Validation dialog for this file should look something
+ /// like this:
+ ///
+ ///
+ ///
+ /// The following is a similar example but it demonstrates how to
+ /// pre-populate a default choice.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_list_strings2.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Select value in cell D2:")?;
+ /// #
+ /// let data_validation =
+ /// DataValidation::new().allow_list_strings(&["Pass", "Fail", "Incomplete"])?;
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ ///
+ /// // Add a default string to the cell with the data validation
+ /// // to pre-populate a default choice.
+ /// worksheet.write(1, 3, "Pass")?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
pub fn allow_list_strings(
mut self,
list: &[impl AsRef],
@@ -146,20 +571,125 @@ impl DataValidation {
Ok(self)
}
- /// Set the TODO
+ /// Set a data validation rule to restrict cell input to a selection of
+ /// strings via a dropdown menu and a cell range reference.
///
- /// TODO
+ /// The strings for the dropdown should be placed somewhere in the
+ /// worksheet/workbook and should be referred to via a cell range reference
+ /// represented by a [`Formula`], see [Using cell references in Data
+ /// Validations] and the example below.
///
- pub fn allow_list_formula(mut self, rule: Formula) -> DataValidation {
- let formula = rule.expand_formula(true).to_string();
+ /// # Parameters
+ /// * `list` - A cell range reference such as `=B1:B9`, `=$B$1:$B$9` or
+ /// `=Sheet2!B1:B9` using a [`Formula`]. See [Using cell references in
+ /// Data Validations].
+ ///
+ /// [Using cell references in Data Validations]:
+ /// #using-cell-references-in-data-validations
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts users to a selection of values from a dropdown list. The list data
+ /// is provided from a cell range.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_list_formula.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Select value in cell D2:")?;
+ /// #
+ /// // Write the string list data to some cells.
+ /// let string_list = ["Pass", "Fail", "Incomplete"];
+ /// worksheet.write_column(1, 5, string_list)?;
+ ///
+ /// let data_validation = DataValidation::new().allow_list_formula("F2:F4".into());
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// Output file:
+ ///
+ ///
+ ///
+ /// The Excel Data Validation dialog for this file should look something
+ /// like this:
+ ///
+ ///
+ ///
+ pub fn allow_list_formula(mut self, list: Formula) -> DataValidation {
+ let formula = list.expand_formula(true).to_string();
self.rule = DataValidationRuleInternal::ListSource(formula);
self.validation_type = DataValidationType::List;
self
}
- /// Set the TODO
+ /// Set a data validation to limit input to dates using defined rules.
+ ///
+ /// Set a data validation rule to restrict cell input to date values based
+ /// on [`DataValidationRule`] rules such as "between" or "less than". Excel
+ /// refers to this data validation type as "Date".
+ ///
+ /// The method uses dates that implement [`IntoExcelDateTime`]. The main
+ /// date type supported is [`ExcelDateTime`]. If the `chrono` feature is
+ /// enabled you can use [`chrono::NaiveDate`].
+ ///
+ /// [`chrono::NaiveDate`]:
+ /// https://docs.rs/chrono/latest/chrono/naive/struct.NaiveDate.html
+ ///
+ /// # Parameters
+ ///
+ /// * `rule` - A [`DataValidationRule`] with [`IntoExcelDateTime`] values.
+ ///
+ /// # Examples
///
- /// TODO
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts input to date values in a fixed range.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_date.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, ExcelDateTime, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+ /// #
+ /// let data_validation = DataValidation::new().allow_date(DataValidationRule::Between(
+ /// ExcelDateTime::parse_from_str("2025-01-01")?,
+ /// ExcelDateTime::parse_from_str("2025-12-12")?,
+ /// ));
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// The Excel Data Validation dialog for this file should look something
+ /// like this:
+ ///
+ ///
///
pub fn allow_date(
mut self,
@@ -170,9 +700,24 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation to limit input to dates using defined rules and a
+ /// cell reference.
+ ///
+ /// Set a data validation rule to restrict cell input to date values based
+ /// on [`DataValidationRule`] rules such as "between" or "less than". Excel
+ /// refers to this data validation type as "Date".
+ ///
+ /// The values used for the rules should be a cell reference represented by
+ /// a [`Formula`], see [Using cell references in Data Validations] and the
+ /// `allow_TYPE_formula()` examples above.
+ ///
+ /// # Parameters
+ ///
+ /// * `rule` - A [`DataValidationRule`] with cell references using
+ /// [`Formula`] values. See [Using cell references in Data Validations].
///
- /// TODO
+ /// [Using cell references in Data Validations]:
+ /// #using-cell-references-in-data-validations
///
pub fn allow_date_formula(mut self, rule: DataValidationRule) -> DataValidation {
self.rule = rule.to_internal_rule();
@@ -180,9 +725,59 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation to limit input to time values using defined rules.
+ ///
+ /// Set a data validation rule to restrict cell input to time values based
+ /// on [`DataValidationRule`] rules such as "between" or "less than". Excel
+ /// refers to this data validation type as "Time".
+ ///
+ /// The method uses time types that implement [`IntoExcelDateTime`]. The
+ /// main time type supported is [`ExcelDateTime`]. If the `chrono` feature
+ /// is enabled you can use [`chrono::NaiveTime`].
+ ///
+ /// [`chrono::NaiveTime`]:
+ /// https://docs.rs/chrono/latest/chrono/naive/struct.NaiveTime.html
+ ///
+ /// # Parameters
+ ///
+ /// * `rule` - A [`DataValidationRule`] with [`IntoExcelDateTime`] values.
///
- /// TODO
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts input to time values in a fixed range.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_time.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, ExcelDateTime, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+ /// #
+ /// let data_validation = DataValidation::new().allow_time(DataValidationRule::Between(
+ /// ExcelDateTime::parse_from_str("6:00")?,
+ /// ExcelDateTime::parse_from_str("12:00")?,
+ /// ));
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// The Excel Data Validation dialog for this file should look something
+ /// like this:
+ ///
+ ///
///
pub fn allow_time(
mut self,
@@ -193,9 +788,24 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation to limit input to time values using defined rules
+ /// and a cell reference.
+ ///
+ /// Set a data validation rule to restrict cell input to time values based
+ /// on [`DataValidationRule`] rules such as "between" or "less than". Excel
+ /// refers to this data validation type as "Time".
///
- /// TODO
+ /// The values used for the rules should be a cell reference represented by
+ /// a [`Formula`], see [Using cell references in Data Validations] and the
+ /// `allow_TYPE_formula()` examples above.
+ ///
+ /// # Parameters
+ ///
+ /// * `rule` - A [`DataValidationRule`] with cell references using
+ /// [`Formula`] values. See [Using cell references in Data Validations].
+ ///
+ /// [Using cell references in Data Validations]:
+ /// #using-cell-references-in-data-validations
///
pub fn allow_time_formula(mut self, rule: DataValidationRule) -> DataValidation {
self.rule = rule.to_internal_rule();
@@ -203,9 +813,53 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation to limit input to string lengths using defined
+ /// rules.
+ ///
+ /// Set a data validation rule to restrict cell input to string lengths
+ /// based on [`DataValidationRule`] rules such as "between" or "less than".
+ /// Excel refers to this data validation type as "Text length" but it
+ /// equates to any Rust type that can convert [`Into`] a [`u32`] (`u64`
+ /// values or strings of that length aren't supported by Excel).
+ ///
+ /// # Parameters
+ ///
+ /// * `rule` - A [`DataValidationRule`] with [`u32`] values.
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts input to strings whose lengths is in a fixed range.
///
- /// TODO
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_text_length.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+ /// #
+ /// let data_validation =
+ /// DataValidation::new().allow_text_length(DataValidationRule::Between(4, 8));
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// The Excel Data Validation dialog for this file should look something
+ /// like this:
+ ///
+ ///
///
pub fn allow_text_length(mut self, rule: DataValidationRule) -> DataValidation {
self.rule = rule.to_internal_rule();
@@ -213,9 +867,24 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation to limit input to string lengths using defined
+ /// rules and a cell reference.
+ ///
+ /// Set a data validation rule to restrict cell input to string lengths
+ /// based on [`DataValidationRule`] rules such as "between" or "less than".
+ /// Excel refers to this data validation type as "Text length".
+ ///
+ /// The values used for the rules should be a cell reference represented by
+ /// a [`Formula`], see [Using cell references in Data Validations] and the
+ /// `allow_TYPE_formula()` examples above.
+ ///
+ /// # Parameters
///
- /// TODO
+ /// * `rule` - A [`DataValidationRule`] with cell references using
+ /// [`Formula`] values. See [Using cell references in Data Validations].
+ ///
+ /// [Using cell references in Data Validations]:
+ /// #using-cell-references-in-data-validations
///
pub fn allow_text_length_formula(
mut self,
@@ -226,47 +895,130 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set a data validation to limit input based on a custom formula.
+ ///
+ /// Set a data validation rule to restrict cell input based on an Excel
+ /// formula that returns a boolean value. Excel refers to this data
+ /// validation type as "Custom".
+ ///
+ /// # Parameters
+ ///
+ /// * `rule` - A [`Formula`] value. You should ensure that the formula is
+ /// valid in Excel.
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts input to text/strings that are uppercase.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_custom.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Enter uppercase string in D2:")?;
+ /// #
+ /// let data_validation =
+ /// DataValidation::new().allow_custom("=AND(ISTEXT(D2), EXACT(D2, UPPER(D2)))".into());
///
- /// TODO
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
///
- pub fn allow_custom_formula(mut self, rule: Formula) -> DataValidation {
+ /// The Excel Data Validation dialog for this file should look something
+ /// like this:
+ ///
+ ///
+ ///
+ pub fn allow_custom(mut self, rule: Formula) -> DataValidation {
let formula = rule.expand_formula(true).to_string();
self.rule = DataValidationRuleInternal::CustomFormula(formula);
self.validation_type = DataValidationType::Custom;
self
}
- /// Set the TODO
+ /// Set a data validation to allow any input data.
///
- /// TODO
+ /// The "Any" data validation type doesn't restrict data input and is mainly
+ /// used allow access to the "Input Message" dialog when a user enters data
+ /// in a cell.
+ ///
+ /// This is the default validation type for [`DataValidation`] if no other
+ /// `allow_TYPE()` method is used. Situations where this type of data
+ /// validation are required are uncommon.
+ ///
+ pub fn allow_any_value(mut self) -> DataValidation {
+ self.rule = DataValidationRuleInternal::EqualTo(String::new());
+ self.validation_type = DataValidationType::Any;
+ self
+ }
+
+ /// Set the data validation option that defines how blank cells are handled.
+ ///
+ /// By default Excel data validations have an "Ignore blank" option turned
+ /// on. This allows the user to optionally leave the cell blank and not
+ /// enter any value. This is generally the best default option since it
+ /// allows users to exit the cell without inputting any data.
+ ///
+ ///
+ ///
+ /// If you need to ensure that the user inserts some information then you
+ /// can use `ignore_blank()` to turn this option off.
+ ///
+ /// # Parameters
+ ///
+ /// * `enable` - Turn the property on/off. It is on by default.
///
pub fn ignore_blank(mut self, enable: bool) -> DataValidation {
self.ignore_blank = enable;
self
}
- /// Set the TODO
+ /// Toggle option to show an input message when the cell is entered.
///
- /// TODO
+ /// This function is used to toggle the option that controls whether an
+ /// input message is shown when a data validation cell is entered.
+ ///
+ /// The option only has an effect if there is an input message, so for the
+ /// majority of use cases it isn't required.
+ ///
+ /// See also [`DataValidation::set_input_message()`] below.
+ ///
+ /// # Parameters
+ ///
+ /// * `enable` - Turn the property on/off. It is on by default.
///
pub fn show_input_message(mut self, enable: bool) -> DataValidation {
self.show_input_message = enable;
self
}
- /// Set the TODO
+ /// Set the title for the input message when the cell is entered.
///
- /// TODO
+ /// This option is used to set a title in bold for the input message when a
+ /// data validation cell is entered.
///
- pub fn show_error_message(mut self, enable: bool) -> DataValidation {
- self.show_error_message = enable;
- self
- }
-
- /// Set the TODO
+ /// The title is only visible if there is also an input message. See the
+ /// [`DataValidation::set_input_message()`] example below.
+ ///
+ /// Note, Excel limits the title to 32 characters.
///
- /// TODO
+ /// # Parameters
+ ///
+ /// * `text` - Title string. Must be less than or equal to the Excel limit
+ /// of 32 characters.
///
pub fn set_input_title(mut self, text: impl Into) -> DataValidation {
let text = text.into();
@@ -283,9 +1035,56 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set the input message when a data validation cell is entered.
+ ///
+ /// This option is used to set an input message when a data validation cell
+ /// is entered. This can we used to explain to the user what the data
+ /// validation rules are for the cell.
+ ///
+ /// Note, Excel limits the message text to 255 characters.
+ ///
+ /// # Parameters
+ ///
+ /// * `text` - Message string. Must be less than or equal to the Excel limit
+ /// of 255 characters. The string can contain newlines to split it over
+ /// several lines.
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// uses an input message to explain to the user what type of input is
+ /// required.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_set_input_message.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Enter rating in cell D2:")?;
+ /// #
+ /// let data_validation = DataValidation::new()
+ /// .allow_whole_number(DataValidationRule::Between(1, 5))
+ /// .set_input_title("Enter a star rating!")
+ /// .set_input_message("Enter rating 1-5.\nWhole numbers only.");
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ /// #
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// Output file:
///
- /// TODO
+ ///
///
pub fn set_input_message(mut self, text: impl Into) -> DataValidation {
let text = text.into();
@@ -302,9 +1101,69 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Toggle option to show an error message when there is a validation error.
+ ///
+ /// This function is used to toggle the option that controls whether an
+ /// error message is shown when there is a validation error.
+ ///
+ /// If this option is toggled off then any data can be entered in a cell and
+ /// an error message will not be raised, which has limited practical
+ /// applications for a data validation.
+ ///
+ /// # Parameters
+ ///
+ /// * `enable` - Turn the property on/off. It is on by default.
+ ///
+ pub fn show_error_message(mut self, enable: bool) -> DataValidation {
+ self.show_error_message = enable;
+ self
+ }
+
+ /// Set the title for the error message when there is a validation error.
+ ///
+ /// This option is used to set a title in bold for the error message when
+ /// there is a validation error.
+ ///
+ /// Note, Excel limits the title to 32 characters.
+ ///
+ /// # Parameters
///
- /// TODO
+ /// * `text` - Title string. Must be less than or equal to the Excel limit
+ /// of 32 characters.
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// shows a custom error title.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_set_error_title.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+ /// #
+ /// let data_validation = DataValidation::new()
+ /// .allow_whole_number(DataValidationRule::Between(1, 10))
+ /// .set_error_title("Danger, Will Robinson!");
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ ///
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// Output file:
+ ///
+ ///
///
pub fn set_error_title(mut self, text: impl Into) -> DataValidation {
let text = text.into();
@@ -321,9 +1180,54 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set the error message when a data validation cell is entered.
+ ///
+ /// This option is used to set an error message when a data validation cell
+ /// is entered. This can we used to explain to the user what the data
+ /// validation rules are for the cell.
+ ///
+ /// Note, Excel limits the message text to 255 characters.
+ ///
+ /// # Parameters
+ ///
+ /// * `text` - Message string. Must be less than or equal to the Excel limit
+ /// of 255 characters. The string can contain newlines to split it over
+ /// several lines.
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// shows a custom error message.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_set_error_message.rs
+ /// #
+ /// # use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+ /// #
+ /// # fn main() -> Result<(), XlsxError> {
+ /// # // Create a new Excel file object.
+ /// # let mut workbook = Workbook::new();
+ /// # let worksheet = workbook.add_worksheet();
+ /// #
+ /// # worksheet.write(1, 0, "Enter value in cell D2:")?;
+ /// #
+ /// let data_validation = DataValidation::new()
+ /// .allow_whole_number(DataValidationRule::Between(1, 10))
+ /// .set_error_title("Value outside allowed range")
+ /// .set_error_message("The input value must be an integer in the range 1-10.");
///
- /// TODO
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ ///
+ /// # // Save the file.
+ /// # workbook.save("data_validation.xlsx")?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// Output file:
+ ///
+ ///
///
pub fn set_error_message(mut self, text: impl Into) -> DataValidation {
let text = text.into();
@@ -340,42 +1244,38 @@ impl DataValidation {
self
}
- /// Set the TODO
+ /// Set the style of the error dialog type for a data validation.
+ ///
+ /// Set the error dialog to be either "Stop" (the default), "Warning" or
+ /// "Information". This option only has an effect on Windows.
///
- /// TODO
+ /// # Parameters
+ ///
+ /// * `error_style` - A [`DataValidationErrorStyle`] enum value.
///
pub fn set_error_style(mut self, error_style: DataValidationErrorStyle) -> DataValidation {
self.error_style = error_style;
self
}
- /// Set an additional multi-cell range for the conditional format.
+ /// Set an additional multi-cell range for the data validation.
///
- /// The `set_multi_range()` method is used to extend a conditional
- /// format over non-contiguous ranges like `"B3:D6 I3:K6 B9:D12
- /// I9:K12"`.
- ///
- /// See [Selecting a non-contiguous
- /// range](crate::conditional_format#selecting-a-non-contiguous-range)
- /// for more information.
+ /// The `set_multi_range()` method is used to extend a data validation
+ /// over non-contiguous ranges like `"B3 I3 B9:D12 I9:K12"`.
///
/// # Parameters
///
/// * `range` - A string like type representing an Excel range.
///
- /// Note, you can use an Excel range like `"$B$3:$D$6,$I$3:$K$6"` or
- /// omit the `$` anchors and replace the commas with spaces to have a
- /// clearer range like `"B3:D6 I3:K6"`. The documentation and examples
- /// use the latter format for clarity but it you are copying and
- /// pasting from Excel you can use the first format.
- ///
- /// Note, if the range is invalid then Excel will omit it silently.
- ///
pub fn set_multi_range(mut self, range: impl Into) -> DataValidation {
self.multi_range = range.into().replace('$', "").replace(',', " ");
self
}
+ // -----------------------------------------------------------------------
+ // Crate level helper methods.
+ // -----------------------------------------------------------------------
+
// The "Any" validation type should be ignored if it doesn't have any input
// or error titles or messages. This is the same rule as Excel.
pub(crate) fn is_invalid_any(&mut self) -> bool {
@@ -389,12 +1289,12 @@ impl DataValidation {
/// Trait to map rust types into data validation types
///
-/// The `IntoDataValidationValue` trait is used to map Rust types like
-/// strings, numbers, dates, times and formulas into a generic type that can be
-/// used to replicate Excel data types used in Data Validation. TODO
+/// The `IntoDataValidationValue` trait is used to map Rust types like numbers,
+/// dates, times and formulas into a generic type that can be used to replicate
+/// Excel data types used in Data Validation.
///
pub trait IntoDataValidationValue {
- /// Function to turn types into a TODO enum value.
+ /// Function to turn types into a string value.
fn to_string_value(&self) -> String;
}
@@ -482,41 +1382,27 @@ impl IntoDataValidationValue for &NaiveTime {
}
}
-//#[cfg(feature = "chrono")]
-//#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
-//data_validation_value_from_type!(&NaiveDate & NaiveDateTime & NaiveTime);
-
// -----------------------------------------------------------------------
// DataValidationType
// -----------------------------------------------------------------------
-/// The `DataValidationType` enum defines TODO
-///
-///
+/// The `DataValidationType` enum defines the type of data validation.
#[derive(Clone, Eq, PartialEq)]
-pub enum DataValidationType {
- /// TODO
+pub(crate) enum DataValidationType {
Whole,
- /// TODO
Decimal,
- /// TODO
Date,
- /// TODO
Time,
- /// TODO
TextLength,
- /// TODO
Custom,
- /// TODO
List,
- /// TODO
Any,
}
@@ -539,34 +1425,35 @@ impl fmt::Display for DataValidationType {
// DataValidationRule
// -----------------------------------------------------------------------
-/// The `DataValidationRule` enum defines the conditional format rule for
+/// The `DataValidationRule` enum defines the data validation rule for
/// [`DataValidation`].
///
-///
#[derive(Clone)]
pub enum DataValidationRule {
- /// TODO.
+ /// Restrict cell input to values that are equal to the target value.
EqualTo(T),
- /// TODO.
+ /// Restrict cell input to values that are not equal to the target value.
NotEqualTo(T),
- /// TODO.
+ /// Restrict cell input to values that are greater than the target value.
GreaterThan(T),
- /// TODO.
+ /// Restrict cell input to values that are greater than or equal to the
+ /// target value.
GreaterThanOrEqualTo(T),
- /// TODO.
+ /// Restrict cell input to values that are less than the target value.
LessThan(T),
- /// TODO.
+ /// Restrict cell input to values that are less than or equal to the target
+ /// value.
LessThanOrEqualTo(T),
- /// TODO.
+ /// Restrict cell input to values that are between the target values.
Between(T, T),
- /// TODO.
+ /// Restrict cell input to values that are not between the target values.
NotBetween(T, T),
}
@@ -606,7 +1493,8 @@ impl DataValidationRule {
// DataValidationRuleInternal
// -----------------------------------------------------------------------
-// TODO
+// This is a variation on `DataValidationRule` that is used for internal storage
+// of the validation rule. It only uses the String type.
#[derive(Clone)]
pub(crate) enum DataValidationRuleInternal {
EqualTo(String),
@@ -651,18 +1539,18 @@ impl fmt::Display for DataValidationRuleInternal {
// DataValidationErrorStyle
// -----------------------------------------------------------------------
-/// The `DataValidationErrorStyle` enum defines TODO
-///
+/// The `DataValidationErrorStyle` enum defines the type of error dialog that is
+/// shown when there is and error in a data validation.
///
#[derive(Clone)]
pub enum DataValidationErrorStyle {
- /// TODO
+ /// Show a "Stop" dialog. This is the default.
Stop,
- /// TODO
+ /// Show a "Warning" dialog.
Warning,
- /// TODO
+ /// Show an "Information" dialog.
Information,
}
diff --git a/src/data_validation/tests.rs b/src/data_validation/tests.rs
index cf3d03ff..2455ff79 100644
--- a/src/data_validation/tests.rs
+++ b/src/data_validation/tests.rs
@@ -942,7 +942,7 @@ mod data_validation_tests {
let mut worksheet = Worksheet::new();
worksheet.set_selected(true);
- let data_validation = DataValidation::new().allow_custom_formula(Formula::new("=6"));
+ let data_validation = DataValidation::new().allow_custom(Formula::new("=6"));
worksheet.add_data_validation(0, 0, 0, 0, &data_validation)?;
@@ -981,7 +981,7 @@ mod data_validation_tests {
let mut worksheet = Worksheet::new();
worksheet.set_selected(true);
- let data_validation = DataValidation::new().allow_custom_formula("6".into());
+ let data_validation = DataValidation::new().allow_custom("6".into());
worksheet.add_data_validation(0, 0, 0, 0, &data_validation)?;
@@ -1097,6 +1097,49 @@ mod data_validation_tests {
Ok(())
}
+ #[test]
+ fn data_validation_16_3() -> Result<(), XlsxError> {
+ let mut worksheet = Worksheet::new();
+ worksheet.set_selected(true);
+
+ let data_validation = DataValidation::new().allow_list_strings(&[
+ &String::from("Foo"),
+ &String::from("Bar"),
+ &String::from("Baz"),
+ ])?;
+
+ worksheet.add_data_validation(0, 0, 0, 0, &data_validation)?;
+
+ worksheet.assemble_xml_file();
+
+ let got = worksheet.writer.read_to_str();
+ let got = xml_to_vec(got);
+
+ let expected = xml_to_vec(
+ r#"
+
+
+
+
+
+
+
+
+
+
+ "Foo,Bar,Baz"
+
+
+
+
+ "#,
+ );
+
+ assert_eq!(expected, got);
+
+ Ok(())
+ }
+
#[test]
fn data_validation_17_1() -> Result<(), XlsxError> {
let mut worksheet = Worksheet::new();
@@ -1450,7 +1493,7 @@ mod data_validation_tests {
.allow_text_length_formula(DataValidationRule::GreaterThan("B6".into()));
worksheet.add_data_validation(5, 0, 5, 0, &data_validation)?;
- let data_validation = DataValidation::new().allow_custom_formula("B7".into());
+ let data_validation = DataValidation::new().allow_custom("B7".into());
worksheet.add_data_validation(6, 0, 6, 0, &data_validation)?;
worksheet.assemble_xml_file();
diff --git a/src/lib.rs b/src/lib.rs
index 2e367f1e..1236f126 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -186,6 +186,7 @@ mod app;
mod content_types;
mod core;
mod custom;
+mod data_validation;
mod datetime;
mod drawing;
mod error;
@@ -219,7 +220,6 @@ pub mod changelog;
pub mod chart;
pub mod conditional_format;
pub mod cookbook;
-pub mod data_validation;
pub mod sparkline;
pub mod tutorial;
pub mod utility;
@@ -230,6 +230,7 @@ pub mod worksheet;
mod test_functions;
// Re-export the public APIs.
+pub use data_validation::*;
pub use datetime::*;
pub use error::*;
pub use filter::*;
@@ -247,9 +248,6 @@ pub use chart::*;
#[doc(hidden)]
pub use conditional_format::*;
-#[doc(hidden)]
-pub use data_validation::*;
-
#[doc(hidden)]
pub use sparkline::*;
diff --git a/src/worksheet.rs b/src/worksheet.rs
index 5dcc5791..e839f437 100644
--- a/src/worksheet.rs
+++ b/src/worksheet.rs
@@ -6422,17 +6422,15 @@ impl Worksheet {
Ok(self)
}
- /// Add a TODO.
+ /// Add a data validation to one or more cells to restrict user input based
+ /// on types and rules.
///
- /// Conditional formatting is a feature of Excel which allows you to apply a
- /// format to a cell or a range of cells based on certain criteria. This is
- /// generally used to highlight particular values in a range of data.
- ///
- ///
+ /// Data validation is a feature of Excel which allows you to restrict the
+ /// data that a user enters in a cell and to display associated help and
+ /// warning messages. It also allows you to restrict input to values in a
+ /// dropdown list.
///
- /// The [`ConditionalFormat`](crate::data_validation) variants are used to represent the types of
- /// conditional format that can be applied in Excel.
+ /// See [`DataValidation`] for more information and examples.
///
/// # Errors
///
@@ -6440,8 +6438,6 @@ impl Worksheet {
/// worksheet limits.
/// * [`XlsxError::RowColumnOrderError`] - First row larger than the last
/// row.
- /// * [`XlsxError::ConditionalFormatError`] - A general error that is raised
- /// when a conditional formatting parameter is incorrect or missing.
///
/// # Parameters
///
@@ -6449,8 +6445,75 @@ impl Worksheet {
/// * `first_col` - The first row of the range.
/// * `last_row` - The last row of the range.
/// * `last_col` - The last row of the range.
- /// * `data_validation` - A conditional format instance that implements
- /// the [`ConditionalFormat`] trait. TODO
+ /// * `data_validation` - A [`DataValidation`] data validation instance.
+ ///
+ /// # Examples
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// uses an input message to explain to the user what type of input is required.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_intro1.rs
+ /// #
+ /// use rust_xlsxwriter::{DataValidation, DataValidationRule, Workbook, XlsxError};
+ ///
+ /// fn main() -> Result<(), XlsxError> {
+ /// // Create a new Excel file object.
+ /// let mut workbook = Workbook::new();
+ /// let worksheet = workbook.add_worksheet();
+ ///
+ /// worksheet.write(1, 0, "Enter rating in cell D2:")?;
+ ///
+ /// let data_validation = DataValidation::new()
+ /// .allow_whole_number(DataValidationRule::Between(1, 5))
+ /// .set_input_title("Enter a star rating!")
+ /// .set_input_message("Enter rating 1-5.\nWhole numbers only.")
+ /// .set_error_title("Value outside allowed range")
+ /// .set_error_message("The input value must be an integer in the range 1-5.");
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ ///
+ /// // Save the file.
+ /// workbook.save("data_validation.xlsx")?;
+ ///
+ /// Ok(())
+ /// }
+ /// ```
+ ///
+ /// Output file:
+ ///
+ ///
+ ///
+ /// Example of adding a data validation to a worksheet cell. This validation
+ /// restricts users to a selection of values from a dropdown list.
+ ///
+ /// ```
+ /// # // This code is available in examples/doc_data_validation_allow_list_strings.rs
+ /// #
+ /// use rust_xlsxwriter::{DataValidation, Workbook, XlsxError};
+ ///
+ /// fn main() -> Result<(), XlsxError> {
+ /// // Create a new Excel file object.
+ /// let mut workbook = Workbook::new();
+ /// let worksheet = workbook.add_worksheet();
+ ///
+ /// worksheet.write(1, 0, "Select value in cell D2:")?;
+ ///
+ /// let data_validation =
+ /// DataValidation::new().allow_list_strings(&["Pass", "Fail", "Incomplete"])?;
+ ///
+ /// worksheet.add_data_validation(1, 3, 1, 3, &data_validation)?;
+ ///
+ /// // Save the file.
+ /// workbook.save("data_validation.xlsx")?;
+ ///
+ /// Ok(())
+ /// }
+ /// ```
+ ///
+ /// Output file:
+ ///
+ ///
///
pub fn add_data_validation(
&mut self,
@@ -6486,7 +6549,6 @@ impl Worksheet {
cell_range.clone_from(&data_validation.multi_range);
}
-
self.data_validations.insert(cell_range, data_validation);
Ok(self)
@@ -13385,16 +13447,16 @@ impl Worksheet {
DataValidationErrorStyle::Stop => {}
}
- match &data_validation.rule {
- &DataValidationRuleInternal::Between(_, _)
- | DataValidationRuleInternal::CustomFormula(_)
- | DataValidationRuleInternal::ListSource(_) => {
- // Excel doesn't use an operator for these types.
- }
- _ => {
- attributes.push(("operator", data_validation.rule.to_string()));
- }
- };
+ match &data_validation.rule {
+ &DataValidationRuleInternal::Between(_, _)
+ | DataValidationRuleInternal::CustomFormula(_)
+ | DataValidationRuleInternal::ListSource(_) => {
+ // Excel doesn't use an operator for these types.
+ }
+ _ => {
+ attributes.push(("operator", data_validation.rule.to_string()));
+ }
+ };
if data_validation.ignore_blank {
attributes.push(("allowBlank", "1".to_string()));