I have a python 3.7 script that has been developed using the OPENPYXL (v2.5.10) library to take data from a number of excel workbooks, to process that data and then to write to a separate excel workbook. The results workbook contains around 100 named ranges and numerous formula which all work as expected including automatically calculating when the workbook is opened in excel.
I am having trouble with one particular formula group which includes the AGGREGATE function. In this case the formula writes to the results workbook, to the correct cell and in the correct form. While other formulas show the resulting value on opening the workbook, this sequence of formulas only show a result if you select the cell, place the cursor in the formula bar (as if you are editing the formula) and then you push the enter/return key. No change or edit is made to the formula. Once you have done this the formula works as expected.
I have tested this on both the latest macOS and windows versions of excel and I get the same behaviour. I should add that trying the 'calculate now', CtrlShiftAltF9, and 'calculate sheet' options do not have any impact. The only time the formula calculates is if you use the enter/return key.
The code that writes the formula is:
activeSheet.cell(row, col).value = f"=IFERROR(INDEX({rngData}, AGGREGATE(15,3,({rng}={cellRef})/({rng}={cellRef})*ROW({rng}),{nth}),{colIndex}),\"\")"
which gives, for example, a correct result in the excel workbook cell as:
=IFERROR(INDEX(_monthAgedDebt_Data, AGGREGATE(15,3,(_monthAgedDebt_ProjectNumbers=$L$4)/(_monthAgedDebt_ProjectNumbers=$L$4)*ROW(_monthAgedDebt_ProjectNumbers),1),6),"")
So in summary:
the code works as it writes the correct formula to the correct cell and in the correct form
in excel the formula does not automatically calculate but only works if you edit the formula in the cell, make no changes, and push enter/return to exit the edit
Is it an issue with AGGREGATE producing an array result? I chose this form of formula principally because you do not need a CTL-SHIFT-ENTER to make it work. If you enter it directly into a cell in excel you can enter it as a normal formula.
I haven't been able to find help on stack overflow other than this one. However, the solution proposed here doesn't work either.
This question poses a similar issue but has no relevant responses.
This question may hold a clue but I don't seem to be able to make that work as well.
Any thoughts on how to fix this issue appreciated. I am not sure if it is an openpyxl issue or an excel issue and am not sure what else to test.
All - the final answer for completeness.
It turns out that the key to solving this issue lay with OPENPYXL and that the guidance provided in the answer by Charlie Clark to this
question
was correct. I had initially applied the solution incorrectly.
I changed the formula to:
activeSheet.cell(row, col).value = \
f"=IFERROR(INDEX({rngData}, _xlfn.AGGREGATE(15,3,({rng}={cellRef})/({rng}={cellRef})*ROW({rng}),{nth}),{colIndex}),\"\")"
by adding in the '_xlfn.' to the front of the AGGREGATE function statement.
The excel spreadsheet now works as expected without the need to edit the cell containing the formula.
Related
I find myself amazed by the magic of Excel non-transparent automatization. I have office 365.
I have the setup below, column P contains "Current value" that is taken into consideration for reports and column Q (Current formula) actually contains formulas that can be restored to P by removing the #.
Let's take cell P58 as an example:
If I write in P58 the formula =RIGHT([#[Current formula]],len([#[Current formula]])-1) and hit enter, Excel automatically converts it to =365.25/12/7 and sometimes converts it directly to the result of that function 4.35. Yes I said sometimes because I have not figured out the pattern.
I would expect after adding the =Right( formula that I would need to Copy - Paste special Values, and then replace = with = in order for Excel to recognize it as a formula.
The problem is this only happens for one file, my coleague has not been able to replicate it on other files.
I don't have any VBA triggers on Sheet or ThisWorkbook
How can I controll these actions that Excel does?
Oh and by the way, I have Fill formulas in tables to create calculated columns OFF:
Let me know if I need to upload a Demo video, I'm not sure how I would do that on stackoverflow at the moment.
I'm using counting invoice numbers (text) in a table's column, but the Excel formula seems to be confusing some values.
I copied small sample of these - please refer to below:
The formulas are as follow:
=COUNTIFS(A1:A19,A1)
=COUNTIF(A1:A19,A1)
As you can see these invoice numbers differ and the results of these functions suggest as if all were the same.
I googled it for 1 hour but I didn't find such as issue as mine.
If anybody had any clue why could this behave in such way I'll be super grateful!
Rob
Each time you copy down this formula it will add 1 row to each. For example the second row of datas formula will be =COUNTIFS(A2:A20,A2). To lock these cells in the formula use $
Your formula should be =COUNTIFS(A$1:A$19,A1)
I've solved this myself:
ROOTCAUSE
Excel tried to be helpful and read these invoice numbers as actual numbers (despite these being defined already in Power Query as text)
Then, Excel fooled me and despite showing that it works on it as a string (I was evaluating the formula) it worked on it as number
Above means that it transformed exemplary "00100001010000018525" to 1.00001E+17, which cut down this to "100001010000018000" - that's the moment Excel stopped fooling around and showed that value in the formula bar.
I think I don't need to tell why countif perceived all these values as equal.
SOLUTION
I simply appended one letter after each invoice number to get e.g. "00100001010000018525a" what forces Excel to quit its gimmicks and games.
Case closed.
I suspect this is a bug in COUNTIF, or maybe by design.
However, to workaround this in the formula, without having to change your data, try adding a wild-card character:
=COUNTIF(A1:A19,"*"&A1)
I have a list of all of the sheet names in my workbook on Sheet1 and I am trying, without success, to use the INDIRECT function to reference a cell on another sheet using said name. I am aware that this is a common question, I have looked at about 10 other questions/answers on this website in addition to others. For some reason, those solutions are not working and I am kinda losing my mind.
The sheet names are all in column A
They are named after dates (format mm-dd-yy) <- I'm assuming this is the problem?
The cell that I am trying to reference is always in O1 on every sheet in the workbook.
I have tried:
=INDIRECT(A1&"!O1")
=INDIRECT("'"A1"'&!O1")
and a few other amalgamations. Again, I have looked into so many other solutions at this point I am just left with asking for help with my situation, which is apparently unique (or more likely it is some blaring user error). Please help me before immediately removing the post.
If I have this right, the names of your sheets are dates, and you have the names listed as dates in Column A. So, they will appear as dates, but are actually Excel's background number for a date (days since 1/1/1900).
If you use the Formulas tab in the ribbon to Evaluate Formula, you should see the date pop in to your formula as a 5 digit number.
If you are not doing anything else with these dates, you could try selecting column A and formatting as text. This solved the issue in my test setup. This will still work if you are using the date for other functions, but you will have to tell Excel it's a date using DateValue()
After formatting Column A as text, I used =INDIRECT("'"&A1&"'!O1")
Try,
=indirect(text(a1, "\'mm-dd-yy\'\!\O\1"))
I am making a payroll program in Excel and one of my concerns is that the salaries of the employees are searched using the INDEX and MATCH or VLOOKUP function. The problem is if the salaries get updated in the future (e.g. a raise or changes in rates), all the previous entries that used the old salaries will be updated to the new salaries. This is a disaster and would make my entire program useless and inefficient. Therefore I need to automatically lock previous calculated cells after a certain time.
Edit: Note we do not want to do this manually such as copy pasting values only because almost all cells are connected to each other and one mistake by the encoder or if they forget to do this before updating a value, everything will be messed up.
No! Not copying and pasting, there's a simpler way. You want to convert the Formula property of a given cell (what's shown in the formula bar in Excel) into the Value property of the cell (what's shown in the cell on the spreadsheet). For a given range A1:B6 this would done by the statement
Range("A1:B6").formula = Range("A1:B6").value
But there's a quirk in Excel that you can run faster by accessing a Value2 property, so
Range("A1:B6").formula = Range("A1:B6").value2
The rest of the code is left as an exercise for the reader :-)
I have a pretty extensive spreadsheet that stores data over many years, and to help culminate that data I have a had to make multiple summary pages to calculate the data one for each year. I want to instead make a single sheet that will summarize the data and the user can simple select the year they want to view from a drop down menu and all the formulas will automatically calculate the new data. From what I can tell this can be done by using the "indirect" function but I cannot get it to work and am starting to think that function will not work because of the way the formula works. Does anyone have a working method that will generate the desired results.
Manual Formula
=SUMPRODUCT((MONTH('W.A.R. 2016'!$A4:$A369)>=1)*(MONTH('W.A.R. 2016'!$A4:$A369)<=3)*('W.A.R. 2016'!$A4:$A369<=TODAY())*(ISNUMBER(FIND("Work",'W.A.R. 2016'!B4:B369))+(ISNUMBER(FIND("Wrk/Lve",'W.A.R. 2016'!B4:B369))/2)))
Formula im working on.
=SUMPRODUCT((MONTH(INDIRECT("'("&O2&")'!$A4:$A369"))>=1)*(MONTH(INDIRECT("'("&O2&")'!$A4:$A369"))<=3)*(INDIRECT("'("&O2&")'!$A4:$A369")<=TODAY())*(ISNUMBER(FIND("Work",INDIRECT("'("&O2&")'!$A4:$A369")))+(ISNUMBER(FIND("Wrk/Lve",INDIRECT("'("&O2&")'!$A4:$A369")))/2)))
In theory I cannot see why its not working but I think it the way indirect pulls the data.
I can spot a couple of issues.
This has unnecessary brackets around the sheet name:
INDIRECT("'("&O2&")'!$A4:$A369")
It will produce a string like: '(W.A.R. 2016)'!$A4:$A369
You just want to use:
INDIRECT("'" & O2 & "'!$A4:$A369")
There is some inconsistency in your formulas
The first formula searches for "Work" in B4:B369 and "Wrk/Lve" in B4:B369, whereas the second formula has the ranges swapped around.
The best advice I can give on trying to figure out where a formula is going wrong is using the Evaluate Formula tool.
Select the cell that has the formula, go to the Data tab on the ribbon and click Evaluate Formula. It will pop up a dialog that allow you to step through each part of the formula as it calculates. From there you should be able to see what's going wrong.