Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CustomConditionalFormat applied to a RangeAreas behaves differently depending on the Range used to fetch the ConditionalFormat #5194

Closed
sndurkin opened this issue Dec 16, 2024 · 7 comments
Assignees
Labels
Area: Excel Issue related to Excel add-ins Resolution: by design Issue is by design Status: in backlog Issue is being tracked in the backlog but timeline for resolution is unknown

Comments

@sndurkin
Copy link

sndurkin commented Dec 16, 2024

Provide required information needed to triage your issue

Your Environment

  • Platform [PC desktop, Mac, iOS, Office on the web]: PC desktop
  • Host [Excel, Word, PowerPoint, etc.]: Excel
  • Office version number: 16.0.18227.20152
  • Operating System: Windows 10

Expected behavior

When updating the formula for a CustomConditionalFormat applied to a RangeAreas, I expected the formula to be applied as-is, without adjustment. In the example ScriptLab script, the formula I provide is =C1 = 1. I expected it to remain that after applying it.

Current behavior

The formula is adjusted to =A1 = 1 after applying it. I believe this happens because the CustomConditionalFormat is applied to a RangeAreas that is composed of both C1 and E1, but the CustomConditionalFormat instance is fetched from cell E1 (the 2nd Range from the RangeAreas) rather than from cell C1.

Steps to reproduce

  1. Import and run the provided ScriptLab script.
  2. Click the Setup button, which will create a CustomConditionalFormat for cells C1 & E1, highlighting cells in green if they equal 1 using formula =C1 = 1.
  3. Click the Run button, which should fetch the CustomConditionalFormat from cell E1 and set the exact same formula, =C1 = 1 again.

Link to live example(s)

https://gist.github.com/sndurkin/a45541e3f07d791996e4efa33cabe1a0

Provide additional details

N/A

Context

I would expect the CustomConditionalFormat to behave the same regardless of which Range within the RangeAreas it was fetched from, presumably because it's the exact same conditional format. I don't really have a workaround for this, because even if I derived the first Range associated with the RangeAreas for the CustomConditionalFormat, I wouldn't necessarily know which CustomConditionalFormat from the first Range is the same as the one I originally fetched, because there is no globally unique id I can use to compare them.

Useful logs

image

@microsoft-github-policy-service microsoft-github-policy-service bot added the Area: Excel Issue related to Excel add-ins label Dec 16, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs: attention 👋 Waiting on Microsoft to provide feedback label Dec 16, 2024
@RuizhiSunMS RuizhiSunMS added Needs: author feedback Waiting for author (creator) of Issue to provide more info and removed Needs: attention 👋 Waiting on Microsoft to provide feedback labels Dec 16, 2024
@RuizhiSunMS
Copy link
Contributor

RuizhiSunMS commented Dec 16, 2024

Hi @sndurkin, thx for reaching out here.
Would you please try to add formula like "=$c$1 =1"? This change works for me.

@sndurkin
Copy link
Author

sndurkin commented Dec 16, 2024

Hi @RuizhiSunMS, thanks for the response. I don't think that will work because that's fundamentally a different formula. My original formula says: If any cell in the range(s) equals 1, highlight it green

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: attention 👋 Waiting on Microsoft to provide feedback and removed Needs: author feedback Waiting for author (creator) of Issue to provide more info labels Dec 16, 2024
@RuizhiSunMS RuizhiSunMS added Status: in backlog Issue is being tracked in the backlog but timeline for resolution is unknown and removed Needs: attention 👋 Waiting on Microsoft to provide feedback labels Dec 17, 2024
@RuizhiSunMS
Copy link
Contributor

@sndurkin, I think I got your point. Mark it as #9626786 into our backlog. I will involve experts to discuss this behavior. Will reply here if any update.

@qinliuMSFT
Copy link
Member

Hi @sndurkin ,

Would you please try the following script? I changed to formulaR1C1: "=RC = 1" ,which means each cell in that range will check if its own value is 1.

async function run() {
  await Excel.run(async (context) => {
    // Reproduce bug
    let sheet = context.workbook.worksheets.getItem("Sheet1");
    let E1 = sheet.getRange("E1");
    let cf = E1.conditionalFormats.getItemAt(0);
    cf.load("custom/rule");
    ranges = cf.getRanges();
    ranges.load("address");
    await context.sync();

    console.log(ranges.address);
    console.log(cf.custom.rule);

    cf.setRanges(ranges);
    cf.custom.rule.formulaR1C1 = `=RC = 1`;
    await context.sync();

    cf.load("custom/rule");
    await context.sync();
    console.log(cf.custom.rule);
  });
}

@qinliuMSFT qinliuMSFT added the Needs: author feedback Waiting for author (creator) of Issue to provide more info label Dec 27, 2024
@sndurkin
Copy link
Author

sndurkin commented Dec 28, 2024

Hi @qinliuMSFT, that does seem to work. AFAIK the Excel.Application.ConvertFormula API isn't ported to the JS API yet, so I'll use another worksheet to convert the A1-style formula that I have into R1C1 (by setting Range.formulas then reading Range.formulasR1C1) so I can utilize this workaround. Thanks!

I would still argue that this bug should stay open; IMO the CustomConditionalFormat object should behave the same regardless of which cell is used to fetch it.

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: attention 👋 Waiting on Microsoft to provide feedback and removed Needs: author feedback Waiting for author (creator) of Issue to provide more info labels Dec 28, 2024
@qinliuMSFT
Copy link
Member

Hi @sndurkin, Happy New Year!

The behavior you're observing is by design due to how Excel handles relative references in conditional formatting rules. Also, the logic for getting formulas and putting formulas is slightly different. When you get the formula from a conditional format, it retrieves the formula relative to the top-left cell of the range. However, when you set the formula, it applies the formula relative to the current range.
When you retrieve the conditional format from E1 and reapply the rule = C1 = 1, Excel again interprets this formula relative to E1 (the current range in context). This means that the formula is now interpreted as true if the R(0)C(-2) = 1. You can try changing the formula to =E1=1 at this time, and you will find that it will become =C1=1 in the end, because it is relative to E1, not C1.

So, to maintain the same conditional formatting rule, the recommended approach is:

  • Get the range from the conditional format,
  • Get the first address of the range,
  • Then retrieve the conditional format again from the refreshed range and then apply the rule.
async function update() {
  await Excel.run(async (context) => {
    let sheet = context.workbook.worksheets.getItem("Sheet1");
    let E1 = sheet.getRange("E1");
    let cf = E1.conditionalFormats.getItemAt(0);
    cf.load("custom/rule");
    let ranges = cf.getRanges();
    ranges.load("address");
    await context.sync();
    console.log(ranges.address);
    console.log(cf.custom.rule);

    let firstAddress = ranges.address.split(",")[0];
    let firstRange = sheet.getRange(firstAddress);
    let cfFromFirstRange = firstRange.conditionalFormats.getItemAt(0);
    cfFromFirstRange.custom.rule.formula = `=C1 = 1`;
    await context.sync();

    cfFromFirstRange.load("custom/rule");
    await context.sync();
    console.log(cfFromFirstRange.custom.rule);
  });
}

This approach and the formulaR1C1 I mentioned last time are both the approaches we advocate, please let us know if you have any other questions.

@qinliuMSFT qinliuMSFT added Resolution: by design Issue is by design and removed Needs: attention 👋 Waiting on Microsoft to provide feedback labels Jan 6, 2025
@sndurkin
Copy link
Author

sndurkin commented Jan 7, 2025

Hi @qinliuMSFT, thanks for the detailed response, the behavior is understandable. I've implemented the formulaR1C1 approach and it's working great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Excel Issue related to Excel add-ins Resolution: by design Issue is by design Status: in backlog Issue is being tracked in the backlog but timeline for resolution is unknown
Projects
None yet
Development

No branches or pull requests

3 participants