How to insert a formula by macro? - excel

The issue has been solved.
It would appear that when I made some changes to capture data a little while ago, I inadvertently broke the order of things. When the above bit of code was running, the [Date Out:] column was indeed empty, so Excel was reporting properly.
I've since reordered the input of formulas and now the sheet works correctly, with credit to #BigBen and #Michael Wycisk.
I created an Excel sheet to draw together the data from several other Excel sheets into one to keep track of a project.
I have a formula that works if it is written into a range of cells with the source data sheet open in the background. If I ask a macro to put it into the required cells as the main sheet opens then the formula fails. By 'fail', I mean the formula checks it's first column to see if data is present or not and then decides that the column is empty regardless, therefore falsely reporting 'nothing sent' if there is a date in the "Date Out" column.
Here is the line in question.
WSR.Range("ReportTable[Latest Portare Instance:]") = "=IFERROR(IF([Date out:]="""",""Nothing Sent"",IF(AND([Received by Serial:]="""",[Received by Asset:]=""""),""Not Received"",IF([Received by Asset:]<>"""",LOOKUP(2,1/('Stock Movement Archive Defra.xlsx'!Archive[Asset No:]=$J2),'Stock Movement Archive Defra.xlsx'!Archive[Location:]),LOOKUP(2,1/('Stock Movement Archive Defra.xlsx'!Archive[S/No:]=$I2),'Stock Movement Archive Defra.xlsx'!Archive[Location:])))),""Issue"")"
It's one of several formulas, all inserted the same way and the rest work. As far as I can tell the formula is being inserted correctly, just that this one stops at the first if statement.
For reference, I have tried changing the first 'if' statement to start IF([Date out:]<>"""", the formula then either states "Nothing Received" where there is no date or pulls the correct data if there is a date. Also tried changing the format of the "Date Out" column.

The formula looks fine for me. The only problem might be that you need to use the .Formula property after the Range object:
WSR.Range("ReportTable[Latest Portare Instance:]").Formula = "=IFERROR(IF([Date out:]="""",""Nothing Sent"",IF(AND([Received by Serial:]="""",[Received by Asset:]=""""),""Not Received"",IF([Received by Asset:]<>"""",LOOKUP(2,1/('Stock Movement Archive Defra.xlsx'!Archive[Asset No:]=$J2),'Stock Movement Archive Defra.xlsx'!Archive[Location:]),LOOKUP(2,1/('Stock Movement Archive Defra.xlsx'!Archive[S/No:]=$I2),'Stock Movement Archive Defra.xlsx'!Archive[Location:])))),""Issue"")"
To make sure that your formula is correct (you say it works fine when typed into the cell), you might type it into the cell, select the cell and then type ?ActiveCell.Formula into the Immediate Window inside the VBE (don't forget to check that the quotation marks are correct).

Related

Excel converts formulas stored with # automatically, how can I controll that

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.

Is there a way to autofill Pi DataLink data using VBA?

I am pulling hourly data out of a server in Osisoft Pi Historian for thousands of distinct data points. The sampling function in question is PISampDat
When I try to copy one row to the next in an effort to save time and effort, I get a message to "Resize to show all values". But this message never updates to actual values when I tell the program to recalculate.
I am left with two options: A) MANUALLY enter the formula parameters for each row, a daunting and torturous task, or B) one of you can mercifully tell me how I can use VBA to autofill all of these rows.
The formula in Cell H280 is the following:
=PISampDat(Sheet1!$T$3,"2019-05-01","2019-06-01","1h",2,Sheet3!$B$280)
This is replicated in all cells up through ABX280 (values for each hour in the month of May, and including midnight of June 1, 2019.)
I don't know where to start in VBA.
I have tried getting rid of the $ before the 280, but then I am prompted "You are not allowed to change part of an array."
Attempts to copy the formula into other lines results in the message "Resize to show all values", but resizing and recalculating does nothing. Either that, or I'm just copying the values from other lines and the formula isn't actually getting called for other data items.
I don't think you need VBA to achieve this. PISampDat uses an array formula so you can either refresh it by using Ctrl+Shift+Enter or by re-opening the function wizard to re-enter a bigger range for the parameter locations.
To go further I'd suggest to use the following resource: Creating Basic Reports with PI Datalink

AGGREGATE formula not automatically calculating when written to results spreadsheet

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.

(MS EXCEL) How do I replace cells with formulas to its calculated value AUTOMATICALLY?

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 :-)

Has anyone experienced Excel Paste-special corrupting data in Tables? (Using 16.0 for Win32)

I have been chasing my tail for half a day with a complex spreadsheet that is REFUSING to behave politely! I am actually trying to fix a problem experienced by another user on a different system, so it is not just me imagining things.
In short, selecting a column of data after a formula edit (to append a character to the previous string, via a holding column) when I do a "simple" paste-in-place, values only, Excel is shifting A2 to A1, A3 to A2 etc, and losing the last value altogether.
[Update: I have realised that is not even attempting to paste the new data to the destination range. It is just bumping the content of the destination column up one cell, losing the old top value entirely, leaving a blank at the bottom, and doing nothing with the copied data at all.]
Example "Drop zone" before copy & paste
Drop zone after "pasting" the copied data
Notes: copied data in the example is a 9x1 range, all values without the terminal 'A'. In the target zone, after the "paste" NO new data are present, the top value, beginning BY has been lost entirely, and the bottom value of the paste range is a copy of the cell value below, outside the paste range, beginning CP.
Sorry I cannot show the "copied" data, I don't have enough 'reputation' points to add a third screen cap!
[Truly UGLY workaround... resize the table to exclude the drop zone. Paste as normal, then reassign the table size. Even after doing this, the same problem persists if I try copy and pasting more data to another part of the table.]
It is ONLY doing this in the context of a Table. Outside the table, behaviour is normal.
This is way beyond the normal scope of minor irritation with Excel, it is monstrous! Recreating the project, even the just the specific table, is hardly a realistic option.
Any ideas what can have caused it to get so bent out of shape? And how to force it to come to its senses?

Resources