diff --git a/NAMESPACE b/NAMESPACE index 5b79434ba..4882faaa7 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -19,6 +19,7 @@ export(create_font) export(create_hyperlink) export(create_numfmt) export(create_sparklines) +export(current_sheet) export(dataframe_to_dims) export(delete_data) export(dims_to_dataframe) @@ -28,6 +29,8 @@ export(get_date_origin) export(get_named_regions) export(guess_col_type) export(int2col) +export(na_strings) +export(next_sheet) export(read_sheet_names) export(read_xlsx) export(read_xml) diff --git a/NEWS.md b/NEWS.md index 69814ce2b..b7ddf2dba 100644 --- a/NEWS.md +++ b/NEWS.md @@ -13,6 +13,10 @@ * Improve date detection in `wb_to_df()`. This improves date and posix detection with custom date formats. [547](https://github.com/JanMarvin/openxlsx2/pull/547) +* `na_strings()` is now used as the explicit default value for `na.strings` parameters in exported workbook functions ([#473](https://github.com/ycphs/openxlsx/issues/473)) + +* waiver functions (i.e., `next_worksheet()`, `current_worksheet()`, and `na_strings()`) are now exports ([#474](https://github.com/ycphs/openxlsx/issues/474)) + ## Fixes * Fixed a bug when loading input with multiple sheets where not every sheet contains a drawing/comment. Previously we assumed that every sheet had a comment and ordered them incorrectly. This caused confusion in spreadsheet software. [536](https://github.com/JanMarvin/openxlsx2/pull/536) @@ -64,7 +68,6 @@ * Only documentation: `openxlsx2` defaults to American English 'color' from now on. Though, we fully support the previous 'colour'. Users will not have to adjust their code. Our documentation only lists `color`, but you can pass `colour` just the same way you used to. [501](https://github.com/JanMarvin/openxlsx2/pull/501) [502](https://github.com/JanMarvin/openxlsx2/pull/502) - *************************************************************************** diff --git a/R/class-workbook-utils.R b/R/class-workbook-utils.R index 0bfd459d2..9396ad32d 100644 --- a/R/class-workbook-utils.R +++ b/R/class-workbook-utils.R @@ -150,14 +150,38 @@ validate_cf_params <- function(params) { # waivers ----------------------------------------------------------------- +#' `openxlsx2` waivers +#' +#' Waiver functions for `openxlsx2` functions +#' +#' @name waivers +#' @returns An object of class `openxlsx2_waiver` +NULL + +#' @rdname waivers +#' @export current_sheet <- function() { structure("current_sheet", class = "openxlsx2_waiver") } +#' @rdname waivers +#' @export next_sheet <- function() { structure("next_sheet", class = "openxlsx2_waiver") } +#' @rdname waivers +#' @export +na_strings <- function() { + structure("na_strings", class = "openxlsx2_waiver") +} + +# helpers ----------------------------------------------------------------- + is_waiver <- function(x) { inherits(x, "openxlsx2_waiver") } + +is_na_strings <- function(x) { + is_waiver(x) && isTRUE(x == "na_strings") +} diff --git a/R/class-workbook-wrappers.R b/R/class-workbook-wrappers.R index bd3822245..45b120908 100644 --- a/R/class-workbook-wrappers.R +++ b/R/class-workbook-wrappers.R @@ -90,7 +90,8 @@ wb_save <- function(wb, path = NULL, overwrite = TRUE) { #' @param sep Only applies to list columns. The separator used to collapse list columns to a character vector e.g. sapply(x$list_column, paste, collapse = sep). #' @param applyCellStyle Should we write cell styles to the workbook #' @param removeCellStyle keep the cell style? -#' @param na.strings na.strings +#' @param na.strings Value used for replacing `NA` values from `x`. Default +#' `na_strings()` uses the special `#N/A` value within the workbook. #' @param inline_strings write characters as inline strings #' @export #' @details Formulae written using write_formula to a Workbook object will not get picked up by read_xlsx(). @@ -115,13 +116,10 @@ wb_add_data <- function( sep = ", ", applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) { assert_workbook(wb) - - if (missing(na.strings)) na.strings <- substitute() - wb$clone(deep = TRUE)$add_data( sheet = sheet, x = x, @@ -175,7 +173,8 @@ wb_add_data <- function( #' @param bandedCols logical. If TRUE, the columns are color banded #' @param applyCellStyle Should we write cell styles to the workbook #' @param removeCellStyle keep the cell style? -#' @param na.strings optional +#' @param na.strings Value used for replacing `NA` values from `x`. Default +#' `na_strings()` uses the special `#N/A` value within the workbook. #' @param inline_strings write characters as inline strings #' #' @details columns of x with class Date/POSIXt, currency, accounting, @@ -205,12 +204,10 @@ wb_add_data_table <- function( bandedCols = FALSE, applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) { assert_workbook(wb) - if (missing(na.strings)) na.strings <- substitute() - wb$clone()$add_data_table( sheet = sheet, x = x, diff --git a/R/class-workbook.R b/R/class-workbook.R index cadd05352..887c6d986 100644 --- a/R/class-workbook.R +++ b/R/class-workbook.R @@ -1031,7 +1031,8 @@ wbWorkbook <- R6::R6Class( #' @param sep sep #' @param applyCellStyle applyCellStyle #' @param removeCellStyle if writing into existing cells, should the cell style be removed? - #' @param na.strings na.strings + #' @param na.strings Value used for replacing `NA` values from `x`. Default + #' `na_strings()` uses the special `#N/A` value within the workbook. #' @param inline_strings write characters as inline strings #' @param return The `wbWorkbook` object add_data = function( @@ -1049,12 +1050,10 @@ wbWorkbook <- R6::R6Class( sep = ", ", applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) { - if (missing(na.strings)) na.strings <- substitute() - write_data( wb = self, sheet = sheet, @@ -1096,7 +1095,8 @@ wbWorkbook <- R6::R6Class( #' @param bandedCols bandedCols #' @param applyCellStyle applyCellStyle #' @param removeCellStyle if writing into existing cells, should the cell style be removed? - #' @param na.strings na.strings + #' @param na.strings Value used for replacing `NA` values from `x`. Default + #' `na_strings()` uses the special `#N/A` value within the workbook. #' @param inline_strings write characters as inline strings #' @returns The `wbWorkbook` object add_data_table = function( @@ -1118,12 +1118,10 @@ wbWorkbook <- R6::R6Class( bandedCols = FALSE, applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) { - if (missing(na.strings)) na.strings <- substitute() - write_datatable( wb = self, sheet = sheet, diff --git a/R/write.R b/R/write.R index 42b24530a..b8e69da56 100644 --- a/R/write.R +++ b/R/write.R @@ -9,8 +9,8 @@ #' @param cells_needed the cells needed #' @param colNames has colNames (only in update_cell) #' @param removeCellStyle remove the cell style (only in update_cell) -#' @param na.strings optional na.string (only in update_cell) -#' @keywords internal +#' @param na.strings Value used for replacing `NA` values from `x`. Default +#' `na_strings()` uses the special `#N/A` value within the workbook.#' @keywords internal #' @noRd inner_update <- function( wb, @@ -20,7 +20,7 @@ inner_update <- function( cells_needed, colNames = FALSE, removeCellStyle = FALSE, - na.strings + na.strings = na_strings() ) { # 1) pull sheet to modify from workbook; 2) modify it; 3) push it back @@ -82,7 +82,7 @@ inner_update <- function( wb$worksheets[[sheet_id]]$dimension <- paste0("") } - if (missing(na.strings)) { + if (is_na_strings(na.strings)) { na.strings <- NULL } @@ -189,7 +189,8 @@ nmfmt_df <- function(x) { #' @param startCol col to place it #' @param applyCellStyle apply styles when writing on the sheet #' @param removeCellStyle keep the cell style? -#' @param na.strings optional na.strings argument. if missing #N/A is used. If NULL no cell value is written, if character or numeric this is written (even if NA is part of numeric data) +#' @param na.strings Value used for replacing `NA` values from `x`. Default +#' `na_strings()` uses the special `#N/A` value within the workbook. #' @param data_table logical. if `TRUE` and `rowNames = TRUE`, do not write the cell containing `"_rowNames_"` #' @param inline_strings write characters as inline strings #' @details @@ -224,13 +225,11 @@ write_data2 <- function( startCol = 1, applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), data_table = FALSE, inline_strings = TRUE ) { - if (missing(na.strings)) na.strings <- substitute() - is_data_frame <- FALSE #### prepare the correct data formats for openxml dc <- openxlsx2_type(data) @@ -358,7 +357,8 @@ write_data2 <- function( na_missing <- FALSE na_null <- FALSE - if (missing(na.strings)) { + + if (is_na_strings(na.strings)) { na.strings <- "" na_missing <- TRUE } else if (is.null(na.strings)) { @@ -661,7 +661,8 @@ write_data2 <- function( #' @param name If not NULL, a named region is defined. #' @param applyCellStyle apply styles when writing on the sheet #' @param removeCellStyle if writing into existing cells, should the cell style be removed? -#' @param na.strings optional na.strings argument. if missing #N/A is used. If NULL no cell value is written, if character or numeric this is written (even if NA is part of numeric data) +#' @param na.strings Value used for replacing `NA` values from `x`. Default +#' `na_strings()` uses the special `#N/A` value within the workbook. #' @param inline_strings optional write strings as inline strings #' @noRd write_data_table <- function( @@ -687,7 +688,7 @@ write_data_table <- function( applyCellStyle = TRUE, removeCellStyle = FALSE, data_table = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) { @@ -715,8 +716,6 @@ write_data_table <- function( startRow <- min(dims[[2]]) } - if (missing(na.strings)) na.strings <- substitute() - ## common part --------------------------------------------------------------- if ((!is.character(sep)) || (length(sep) != 1)) stop("sep must be a character vector of length 1") @@ -946,7 +945,8 @@ write_data_table <- function( #' @param name If not NULL, a named region is defined. #' @param applyCellStyle apply styles when writing on the sheet #' @param removeCellStyle if writing into existing cells, should the cell style be removed? -#' @param na.strings optional na.strings argument. if missing #N/A is used. If NULL no cell value is written, if character or numeric this is written (even if NA is part of numeric data) +#' @param na.strings Value used for replacing `NA` values from `x`. Default +#' `na_strings()` uses the special `#N/A` value within the workbook. #' @param inline_strings write characters as inline strings #' @seealso [write_datatable()] #' @export write_data @@ -1024,12 +1024,10 @@ write_data <- function( name = NULL, applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) { - if (missing(na.strings)) na.strings <- substitute() - write_data_table( wb = wb, sheet = sheet, @@ -1219,7 +1217,8 @@ write_formula <- function( #' @param bandedCols logical. If TRUE, the columns are color banded #' @param applyCellStyle apply styles when writing on the sheet #' @param removeCellStyle if writing into existing cells, should the cell style be removed? -#' @param na.strings optional na.strings argument. if missing #N/A is used. If NULL no cell value is written, if character or numeric this is written (even if NA is part of numeric data) +#' @param na.strings Value used for replacing `NA` values from `x`. Default +#' `na_strings()` uses the special `#N/A` value within the workbook. #' @param inline_strings write characters as inline strings #' @details columns of x with class Date/POSIXt, currency, accounting, #' hyperlink, percentage are automatically styled as dates, currency, accounting, @@ -1333,12 +1332,10 @@ write_datatable <- function( bandedCols = FALSE, applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) { - if (missing(na.strings)) na.strings <- substitute() - write_data_table( wb = wb, sheet = sheet, diff --git a/R/write_xlsx.R b/R/write_xlsx.R index 74cffd4d3..3cfbbf980 100644 --- a/R/write_xlsx.R +++ b/R/write_xlsx.R @@ -286,10 +286,7 @@ write_xlsx <- function(x, file, asTable = FALSE, ...) { tableStyle <- params$tableStyle } - na_strings <- substitute() - if ("na.strings" %in% names(params)) { - na_strings <- params$na.strings - } + na.strings <- params$na.strings %||% na_strings() ## create new Workbook object @@ -380,7 +377,7 @@ write_xlsx <- function(x, file, asTable = FALSE, ...) { tableStyle = tableStyle[[i]], tableName = NULL, withFilter = withFilter[[i]], - na.strings = na_strings + na.strings = na.strings ) } else { write_data( @@ -392,7 +389,7 @@ write_xlsx <- function(x, file, asTable = FALSE, ...) { xy = xy, colNames = colNames[[i]], rowNames = rowNames[[i]], - na.strings = na_strings + na.strings = na.strings ) } diff --git a/man/waivers.Rd b/man/waivers.Rd new file mode 100644 index 000000000..e1cb86585 --- /dev/null +++ b/man/waivers.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class-workbook-utils.R +\name{waivers} +\alias{waivers} +\alias{current_sheet} +\alias{next_sheet} +\alias{na_strings} +\title{\code{openxlsx2} waivers} +\usage{ +current_sheet() + +next_sheet() + +na_strings() +} +\value{ +An object of class \code{openxlsx2_waiver} +} +\description{ +Waiver functions for \code{openxlsx2} functions +} diff --git a/man/wbWorkbook.Rd b/man/wbWorkbook.Rd index 45e08a0dc..8736ad103 100644 --- a/man/wbWorkbook.Rd +++ b/man/wbWorkbook.Rd @@ -575,7 +575,7 @@ add data sep = ", ", applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE )}\if{html}{\out{}} } @@ -611,7 +611,8 @@ add data \item{\code{removeCellStyle}}{if writing into existing cells, should the cell style be removed?} -\item{\code{na.strings}}{na.strings} +\item{\code{na.strings}}{Value used for replacing \code{NA} values from \code{x}. Default +\code{na_strings()} uses the special \verb{#N/A} value within the workbook.} \item{\code{inline_strings}}{write characters as inline strings} @@ -645,7 +646,7 @@ add a data table bandedCols = FALSE, applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE )}\if{html}{\out{}} } @@ -689,7 +690,8 @@ add a data table \item{\code{removeCellStyle}}{if writing into existing cells, should the cell style be removed?} -\item{\code{na.strings}}{na.strings} +\item{\code{na.strings}}{Value used for replacing \code{NA} values from \code{x}. Default +\code{na_strings()} uses the special \verb{#N/A} value within the workbook.} \item{\code{inline_strings}}{write characters as inline strings} } diff --git a/man/wb_add_data_table.Rd b/man/wb_add_data_table.Rd index f7cb8e966..3921dfa24 100644 --- a/man/wb_add_data_table.Rd +++ b/man/wb_add_data_table.Rd @@ -24,7 +24,7 @@ wb_add_data_table( bandedCols = FALSE, applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) } @@ -76,7 +76,8 @@ sep). \item{removeCellStyle}{keep the cell style?} -\item{na.strings}{optional} +\item{na.strings}{Value used for replacing \code{NA} values from \code{x}. Default +\code{na_strings()} uses the special \verb{#N/A} value within the workbook.} \item{inline_strings}{write characters as inline strings} } diff --git a/man/write_data.Rd b/man/write_data.Rd index 3df956229..67203283c 100644 --- a/man/write_data.Rd +++ b/man/write_data.Rd @@ -21,7 +21,7 @@ wb_add_data( sep = ", ", applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) @@ -41,7 +41,7 @@ write_data( name = NULL, applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) } @@ -78,7 +78,8 @@ write_data( \item{removeCellStyle}{if writing into existing cells, should the cell style be removed?} -\item{na.strings}{optional na.strings argument. if missing #N/A is used. If NULL no cell value is written, if character or numeric this is written (even if NA is part of numeric data)} +\item{na.strings}{Value used for replacing \code{NA} values from \code{x}. Default +\code{na_strings()} uses the special \verb{#N/A} value within the workbook.} \item{inline_strings}{write characters as inline strings} } diff --git a/man/write_datatable.Rd b/man/write_datatable.Rd index 531dc36c8..6b1abac20 100644 --- a/man/write_datatable.Rd +++ b/man/write_datatable.Rd @@ -24,7 +24,7 @@ write_datatable( bandedCols = FALSE, applyCellStyle = TRUE, removeCellStyle = FALSE, - na.strings, + na.strings = na_strings(), inline_strings = TRUE ) } @@ -73,7 +73,8 @@ A vector of the form c(startCol, startRow)} \item{removeCellStyle}{if writing into existing cells, should the cell style be removed?} -\item{na.strings}{optional na.strings argument. if missing #N/A is used. If NULL no cell value is written, if character or numeric this is written (even if NA is part of numeric data)} +\item{na.strings}{Value used for replacing \code{NA} values from \code{x}. Default +\code{na_strings()} uses the special \verb{#N/A} value within the workbook.} \item{inline_strings}{write characters as inline strings} }