=IFERROR(VLOOKUP("Processed Units Forecast",'IB ALPS'!$A$59:$K$1000,MATCH(Date1,INDEX('IB ALPS'!$1:$1048576,3,1):INDEX('IB ALPS'!$1:$1048576,3,11),0),FALSE),"N/A")
Hello, so I'm having an issue with this formula. I have a macro that deletes some of the DATA on the IB ALPS sheet. By the time the macro is finished, all of the referenced cells/ranges are fixed, but somewhere in the middle it creates a REF error # $A$59:$K$1000(because of that split second where the cells are deleted). How can I stop excel from editing the function in that 1 second down time that the macro has, or how can I edit the function to keep referring to that range without immediately adding a REF.
If you have the ability to edit the macro, you can temporarily disable calculation for your sheet while deleting the cells:
ActiveWorkbook.Sheets("IB ALPS").EnableCalculation = False
' Some code that deletes rows goes here
ActiveWorkbook.Sheets("IB ALPS").EnableCalculation = True
This should prevent the functions on that sheet from thinking that anything has gone wrong. See the Microsoft documentation on this property for more information.
I am trying to write this VBA so that if cell(U5) = "YES" then range(B5:T5) are locked else range(B5:T5) remains unlocked. Similarly if cell(U6) = "YES" then range(B6:T6) are locked else range(B6:T6) remains unlocked and so on. Unfortunately my codes are not running and I am unable to find the error! Please find my mistake!
From your narrative, I've gathered that you only have to do anything if the values in column U are changed and then only to the cells in B:T on the rows where U has changed.
There is no indication as to what should happen if the cells in column U are neither Yes or No. I've left an area for you to deal with that if you want to.
You were using i + 21 in the column number parameter of cells. This means that the first time the loop goes through it is U5. On the second iteration it is now V6; on the third W7, etc. This is not what your narrative states so I followed the narrative's instructions and assumed a simple coding error. This also means that (if you had run through the code previously) you may have inadvertently 'locked' the wrong cells. If that is the case, you might just want to start on a new worksheet and delete the one you had been working on.
The Worksheet.Protect method has an optional parameter for UserInterfaceOnly. When set to True, the user is restricted by a protected worksheet but no VBA code is similarly protected. This means that you do not have to .Unprotect the worksheet to run your code. I've added a 'helper' sub procedure; run it once and then you do not have to Unprotect and reProtect the worksheet.
If you choose not to use UserInterfaceOnly protection, move the .Protect and .Unprotect statements outside the loop so that they are not performed for each row.
I have an excel sheet that has dde links to real time market data. I use a timer to watch the dde prices every second. Then submit orders when certain conditions are met. I tried an infinite loop with DoEvent in the middle which works for 5 seconds then freezes the workbook.
Is there a way to respond to changes in dde updates? Change event doesn't detect them. It just detects when user makes manual change.
I was told that if I have conditional formatting there's a way to pick up that event. So I can create a cell formula to turn true when my condition is met and then conditional format that cell to some formatting when it's true and then pick up the format change event. Is that possible? If so how. Any suggestions would be appreciated.
To Clarify: I want to pick up an event IN VBA that would submit an order to trade a stock. The way i'm doing this right now is with a timer which loops over all the rows looking for true cell in the trigger column. Once found it shuts off the flag for that row (sets the true condition to false) and submits the order.
The problem is that one second is an eternity for fast moving stocks. So I need an event to be thrown in VBA when a cell in trigger column turns true so I can respond immediately and not wait for the second interval of the timer class.
As far as I know, you can't call on the timer with a value of less than a second. If I could use milliseconds my problem would be solved. I'd just loop over the list every 10 milliseconds.
As far as I know I can't create another thread in VBA. If I could I would make an infinite loop and put it to sleep after every iteration for 10 milliseconds or so.
As far as I know, I can't pull dde directly into VBA or even .net for that matter since MSDN says it's no longer supported.
I hope this clarifies. All suggestion are appreciated.
If you create a dummy function which has your DDE output cells as parameters then you should be able to respond to the Worksheet_Calculate event?
I'm guessing that might work, but I've no experience with DDE: the DDE update may even trigger the Calculate event directly.
If you are asking if you can use conditional formatting to trigger an event, yes that is possible. I am not familiar with the DDE model myself, however, and mixing conditional formatting to trigger an event from a data condition does seem like an extra step, as Stepan1010 notes.
You may want to consider the discussion in Mr Excel in this link, as the issue centers around changing a cell value based changes made to cells from a DDE connection: http://www.mrexcel.com/forum/showthread.php?176508-Comments-VBA-amp-Min-Max
You may also consider using a DoEvent with a loop set for a time period based on how long you will actually implement the macro, if that applies to your application. This SO article is focused on a status bar, but I think the same logic applies in terms of an event execution, say based on a conditional within a loop: Force a screen update in Excel VBA
Hopefully this is helpful to you =)
~JOL
Why don't you just recreate whatever conditional formatting logic you have in that cell into a seperate cell?
For example your conditional formatting logic might highlight a cell when it is above a certain number - you could just put that logic in another cell- eg. =if(A1>100,TRUE,FALSE)
So I guess my question is - Why pick up the format change event when you can just pick up the event itself?
Edit for your clarification:
If you want to run a macro continuously in VBA you don't need a timer - you can just do a continuous loop like this:
Sub macro1()
Dim i As Double
With Sheet1
Do
'.Cells(5, 4).Value = i
i = i + 1
.Cells(1, 1).Value = i
' you are going to want to comment this out if you want to don't need to do other things
DoEvents
If Sheets("Sheet1").Range("A2").Value = True Then
' put your code here.
End If
Loop
End With
End Sub
So I must still be having trouble understanding your situation.
in the Worksheet_Calculate event of my sheet (triggered on SHIFT+F9), I need to override the calculation process. More precisely, I want to disable the default sheet calculation to replace that by some custom calculation. I need to calculate some things, then load some things in between, then compute some other cells, etc... I don't want Excel trying to calculate everything because 1. that takes a while 2. it is useless in my process
Is this possible ?
One approach would be to switch to Manual Calculation mode in the Worksheet_Calculate event, (Application.Calculation=xlManual) do your custom calculation etc, then switch back to automatic calculation (Application.Calculation=xlAutomatic). You would also need to set Application.EnableEvents to false at the start and then back to true at the end to avoid repeated calls to Worksheet_Calculate
I have a rather large workbook that takes a really long time to calculate. It used to be quite a challenge to get it to calculate all the way, since Excel is so eager to silently abort calculation if you so much as look at it.
To help alleviate the problem, I created some VBA code to initiate the the calculation, which is initiated by a form, and the result is that it is not quite as easy to interrupt the calculation process, but it is still possible. (I can easily do this by clicking the close X on the form, but I imagine there are other ways)
Rather than taking more steps to try and make it harder to interrupt calculation, I'd like to have the code detect whether calculation is complete, so it can notify the user rather than just blindly forging on into the rest of the steps in my code. So far, I can't find any way to do that.
I've seen references to Application.CalculationState, but the value is xlDone after I interrupt calculation, even if I interrupt the calculation after a few seconds (it normally takes around an hour).
I can't think of a way to do this by checking the value of cells, since I don't know which one is calculated last. I see that there is a way to mark cells as "dirty" but I haven't been able to find a way to check the dirtiness of a cell. And I don't know if that's even the right path to take, since I'd likely have to check every cell in every sheet.
The act of interrupting calculation does not raise an error, so my ON ERROR doesn't get triggered.
Is there anything I'm missing? Any ideas?
Any ideas?
I think the trick you need to implement (if you're application runs in Excel 2007 or later) is to handle this with the Application.AfterCalculate event, which is raised after both calculation is complete and there are no outstanding queries.
If you've never worked with events in VBA before, there is a good overview from cpearson.com.
The (MSDN) solution by Charles Williams above worked for me where I had 1000's of VLOOKUP's that neeeded to recalculate as the code was changing the lookup value because of an iteration loop. Results were skewed as calculations were not running to 100% completion.
At the beginning of my subroutine the code executes
Application.Calculation = xlManual
This eliminated unnecessary calculations by Excel until I was ready.
Now at the critical point the code executes
Application.Calculation = xlAutomatic
ThisWorkbook.ForceFullCalculation = True
Application.Calculate
Having forced Excel to perform a full calculation, the code could then saved the result and move onto the next iteration ... but before doing so
ThisWorkbook.ForceFullCalculation = False
Application.Calculation = xlManual
Remembering at the very end
Application.Calculation = xlAutomatic
I've never actually used it but I think this might work to prevent calculation from being interrupted.
Application.CalculationInterruptKey = xlNoKey
I think I'm hearing that you need a way to monitor whether each step within the calculations being performed was executed.
Assuming that you're not interested in re-engineering the workbook to use methods that are easier to track than spreadsheet calculations (such as volatile calculations within VBA or Pivot Tables), this may work for you:
Within VB, you can utilize .EnableCalculation and .Calculate to set an entire worksheet as "Dirty" (needing calculation) and then recalculate. The key difference between this and your current process is that we will perform these actions one worksheet at a time in manual mode. By initiating the calculations one worksheet at a time from within VBA, you will be able to perform additional intermediate actions that can be used to track how far you got in the calculation process.
Please note that this approach assumes a fairly linear workbook structure such that your workbook will produce the correct results if we first recalculate Sheet1, then Sheet2, Sheet3, and so on, in whatever order you wish. If your formula dependencies are more "spaghetti" than linear, this probably won't work for you. It also assumes you are working in Excel 2000 or later.
For example, you could write a VBA routine that accomplishes the following steps.
You will need to know your dependencies in order to know which calculations must come before others, and start with the worksheet in a "clean" state where no calculations are currently pending.
Step 1: Set the active sheet to the first worksheet where recalculation is needed
Step 2: Set the calculation mode to manual as follows:
Application.Calculation = xlCalculationManual
Step 3: "Dirty" the entire active sheet as follows:
With ActiveSheet
.EnableCalculation = False
.EnableCalculation = True
Step 4: Initiate a recalculation for this worksheet only (not the entire workbook) using:
.Calculate
End With
Note that if the calculation mode were set to automatic, Step 3 would initiate a re-calculation across the entire workbook. By using manual mode and With, we are constraining that calculation to the current sheet.
Now you have dirtied and re-calculated the first sheet (hurray!). Now, by embedding Steps 3 and 4 above into a For/Each or For/Next loop, you can repeat the process for each worksheet in your workbook. Again, make sure you know the order in which your worksheets need to be calculated (if an order is needed).
Now for the big finish - by creating a counter variable within your loop, you can track how far you got in the calculations by updating your counter variable value each time you complete a worksheet calculation. For example, after you recalculate a worksheet, you can set the counter value to current value + 1 and store the results either in a global variable (so that it will persist even after your VBA routine ends), or in a cell within your worksheet. That way, you can check this value later to see how many worksheets were updated before the calculations finished or were interrupted.
If you have relatively few worksheets in your workbooks, the same approach could be applied to one range at a time rather than a sheet.
I won't go into detail about how to construct a "counter", loops, or global variables here, but if needed, this information can be easily found using your favorite search engine. I would also highly recommend re-enabling automatic calculations once you are done as it is easy to forget that it's been set to manual mode.
I hope this works for you - for more information on calculation modes and recalculation, this is a helpful link:
http://msdn.microsoft.com/en-us/library/bb687891.aspx
Perhaps the following would work:
Do Until Application.CalculationState = xlDone
DoEvents
Loop
Can't say I've tested it, nor that I know how robust the functionality of Application.CalculationState really is to determine whether 'complete' calculation occurred, as opposed to something interrupting the process and flagging the calculation state as done.
Private sub SomeCodeThatGeneratesFormulas
Application.Calculation = xlCalculation.xlCalculationManual
'...Some formulas are copied here'
Application.OnTime DateTime.DateAdd ("s",.01,DateTime.Now), "Module1.CalculateFullRebuildAndSubsequentSteps" 'By using Application.OnTime, this method will be called in a way that locks the end-user out of providing inputs into Excel until the calculation itself is complete.
end sub
public sub CalculateFullRebuildAndSubsequentSteps
Application.CalculateFullRebuild
'...Do next steps, i.e. paste as values'
end sub
On the status bar, right hand side, it will say Calculating (N processors) X% (where N is the number of processors on your computer and X% is how much it has completed) when recalculating. If you don't see text there, it's not recalculating.
I'm using Office 2010, but it should be there in all versions. It's just kinda subtle so it's easy to miss.
Arrays in Excel can be a bit stupid. That is that in order to accomplish some tasks people avoid to use intermediate columns/rows to store (temporary) data, so arrays have to recalculate staff from the beginning every time, thus getting really slow. My Suggestion would be:
fix arrays to avoid multiple searches. Use hidden cells or even hidden sheets
Avoid using A:A and rather use A1:A1000 specially in excel 2007 or later
use formulas to equal zero or error (ex: NA()) while previous items aren't calculated, so you can clearly see if an operation is done at all.
some VBA could be used to inject formulas in place one step at a time, perform calculations, then proceed to next step, but this could mean lots of work...