library(tidyverse)
library(openxlsx2)
setwd("~/omids_excel_challenges/files/")
file <- "CH-024 Hilight merged dcells.xlsx"
wb = wb_load(file)
df = wb$to_df(fill_merged_cells = F, dims = "B2:I14", col_names = T)
process_rows <- function(df, i) {
df[i,] %>%
t() %>%
as.data.frame() %>%
rownames_to_column("row") %>%
select(-row) %>%
mutate(row = i, col = row_number()) %>%
rename(text = 1) %>%
mutate(gr = cumsum(!is.na(text))) %>%
filter(n() > 1, .by = gr) %>%
unite("pos", row, col, sep = "_") %>%
select(pos) %>%
unlist()
}
process_cols <- function(df, i) {
df[,i] %>%
as.data.frame() %>%
mutate(col = i, row = row_number()) %>%
rename(text = 1) %>%
mutate(gr = cumsum(!is.na(text))) %>%
filter(n() > 1, .by = gr) %>%
unite("pos", row, col, sep = "_") %>%
select(pos) %>%
unlist()
}
rows_merged <- map(1:3, ~process_rows(df, .x)) %>% reduce(c) %>% unique()
cols_merged <- map(1:ncol(df), ~process_cols(df, .x)) %>% reduce(c) %>% unique()
merged_cells_positions <- union(rows_merged, cols_merged) %>%
unique()
positions = merged_cells_positions %>%
as.tibble() %>%
separate(value, c("row", "col"), sep = "_") %>%
mutate(row = as.numeric(row), col = as.numeric(col)) %>%
mutate(val = "X")
all_grid = expand.grid(row = 1:12, col = 1:8) %>%
left_join(positions, by = c("row", "col")) %>%
mutate(val = ifelse(is.na(val), "", val)) %>%
pivot_wider(names_from = col, values_from = val) %>%
select(-row)
view(all_grid)Omid - Challenge 24
data-challenges
advanced-exercises
🔰 Highlight Merged cells In Conditional Formatting write a formula to highlight the merged cells.

Challenge Description
🔰 Highlight Merged cells In Conditional Formatting write a formula to highlight the merged cells.
Solutions
Logic:
Reshapes the data into the grain required by the task
Builds the intermediate columns that drive the final result
Strengths:
- The R solution stays close to the workbook rule and keeps the transformation compact.
Areas for Improvement:
- The code assumes the sheet structure and source ranges remain stable.
Gem:
- The strongest part of the solution is choosing the right intermediate representation before shaping the final output.
from openpyxl import load_workbook
import pandas as pd
path = "CH-024 Hilight merged dcells.xlsx"
wb = load_workbook(path)
ws = wb.active
target_rows = range(2, 15) # B2:I14 source region
target_cols = range(2, 10)
merged = set()
for merged_range in ws.merged_cells.ranges:
min_col, min_row, max_col, max_row = merged_range.bounds
for row in range(max(min_row, 2), min(max_row, 14) + 1):
for col in range(max(min_col, 2), min(max_col, 9) + 1):
merged.add((row - 1, col - 1))
rows = []
for r in range(1, 13):
row = []
for c in range(1, 9):
row.append("X" if (r, c) in merged else "")
rows.append(row)
result = pd.DataFrame(rows)
print(result)Logic:
- Applies the rule iteratively until the output stabilizes
Strengths:
- The Python version follows the same rule in a direct dataframe-oriented implementation.
Areas for Improvement:
- The code assumes the workbook layout remains stable, so any sheet redesign would require small adjustments.
Gem:
- The implementation stays close to the original workbook rule instead of adding unnecessary abstraction.
Difficulty Level
This task is moderate:
The core logic is clear, but the correct transformation pattern is not obvious from the raw input.
The challenge combines multiple reshaping, grouping, or parsing steps.