From e1676614bd08fb3d5e25a0bac7e9c8e2a5e14c7b Mon Sep 17 00:00:00 2001 From: Jan Marvin Garbuszus Date: Wed, 24 Jul 2024 00:53:27 +0200 Subject: [PATCH] [read] handle wb_to_df() where shared cells origin is outside of the selected dims region --- R/read.R | 12 +++++++++--- tests/testthat/test-read_from_created_wb.R | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/R/read.R b/R/read.R index 7f0670bad..13d38e0ea 100644 --- a/R/read.R +++ b/R/read.R @@ -427,9 +427,11 @@ wb_to_df <- function( if (any(cc$f_t == "shared")) { - cc_shared <- cc[cc$f_t == "shared", ] - cc_shared <- cc_shared[order(as.integer(cc$f_si)), ] + cc_shared <- wb$worksheets[[sheet]]$sheet_data$cc + cc_shared <- cc_shared[cc_shared$f_t == "shared", ] + cc_shared <- cc_shared[order(as.integer(cc_shared$f_si)), ] + # extend shared formula into all formula cells carry_forward <- function(x) { last_val <- NA for (i in seq_along(x)) { @@ -448,6 +450,7 @@ wb_to_df <- function( FUN = carry_forward ) + # calculate difference for each shared formula to the origin calc_distance <- function(x) { x - x[1] } @@ -458,11 +461,12 @@ wb_to_df <- function( FUN = calc_distance ) cc_shared$rows <- ave( - col2int(cc_shared$row_r), + as.integer(cc_shared$row_r), as.integer(cc_shared$f_si), FUN = calc_distance ) + # TODO skip non A1 shared cells cells <- find_a1_notation(cc_shared$f) repls <- cells @@ -474,6 +478,8 @@ wb_to_df <- function( cc_shared$cols <- NULL cc_shared$rows <- NULL + # reduce and assign + cc_shared <- cc_shared[which(cc_shared$r %in% cc$r), ] cc[match(cc_shared$r, cc$r), ] <- cc_shared } diff --git a/tests/testthat/test-read_from_created_wb.R b/tests/testthat/test-read_from_created_wb.R index 5dfd45664..2e17a68d3 100644 --- a/tests/testthat/test-read_from_created_wb.R +++ b/tests/testthat/test-read_from_created_wb.R @@ -221,3 +221,20 @@ test_that("check_names works", { expect_equal(exp, got) }) + +test_that("shared formulas are handled", { + wb <- wb_workbook()$ + add_worksheet()$ + add_data(x = matrix(rnorm(5*5), ncol = 5, nrow = 5))$ + add_formula(x = "SUM($A2:A2) + B$1", dims = "A8:E12", shared = TRUE) + + exp <- structure( + c("SUM($A4:A4) + B$1", "SUM($A5:A5) + B$1", "SUM($A6:A6) + B$1", + "SUM($A4:B4) + C$1", "SUM($A5:B5) + C$1", "SUM($A6:B6) + C$1", + "SUM($A4:C4) + D$1", "SUM($A5:C5) + D$1", "SUM($A6:C6) + D$1"), + dim = c(3L, 3L), + dimnames = list(c("10", "11", "12"), c("A", "B", "C")) + ) + got <- as.matrix(wb_to_df(wb, dims = "A10:C12", col_names = FALSE, show_formula = TRUE)) + expect_equal(exp, got) +})