Excel not recalculating if formula until it's forced to - vba

I've got a macro which generates a list from a spreadsheet, filters out things we need and don't need and formats it at the end. For filtering out information I am using a simple if formula which is inputted by my macro:
MyRange4.Formula = "=IF(M2<H2+1,""yes"",""no"")"
MyRange4.AutoFill Destination:=Formula3
When you run the macro, it is slowing it down a bit because it has to calculate for over 2000 lines, but it looked fine to me for a while, until we realized some of the lines we should have on the list are not there. When looking into it, I have filtered on the line we wanted, and the if formula was showing "no" which is obviously why it's not got excluded, but after 2-3 second the sheet recalculated and it's changed to "yes". Is there anyway I could force this to happen before the macro filters on the "yes" ones only so I am sure it's all correct?

Could this do the trick for you:
'Above this line: First bit of your code untill calculating formula's
Worksheets("Sheet1").UsedRange.Columns("A:A").Calculate 'Change sheetname and column accordingly
If Not Application.CalculationState = xlDone Then
DoEvents
End If
'Below this line: Second bit of your code, filtering the data

Related

Copy relevant rows and paste to new worksheet

I have multiple sheets which I am looking to copy and paste the relevant cells from rows into a new worksheet. The defining factor is whether the rows are "Live" which is determined by whether today falls between the "start date" and "end date" columns. For all rows that are "live" certain cells on that row should then be copy pasted to the bottom of the list on the new worksheet. I would then repeat these steps for the other worksheets so that the new worksheet essentially contains a summary of all "live" lines from the other sheets.
I then ultimately need to create a button so I can re-run this at the end of each day.
Hoping you can help!
You've defined and explained what you want to do nicely. So the next step would be to start researching the actions you want the code to do:
Start with how to copy rows:
http://www.bluepecantraining.com/copying-moving-rows-columns-excel-vba/
Next is how to find the last used row in a worksheet:
https://powerspreadsheets.com/excel-vba-last-row/
Next is to apply your condition on what rows to copy:
Using VBA to check if a date is between two dates
Next is how to create a for loop that runs the code the desired number of times:
https://www.excel-easy.com/vba/loop.html (a tip is to use the LastRow that you defined via the second link i posted. eg: "For x = 1 To LastRow")
And lastly is how to assign a macro to a button or shape:
https://wellsr.com/vba/2017/excel/how-to-assign-a-macro-to-a-shape-in-excel/
Try to build a code with the help of these links. If you get stuck, come back and show us what you've created and where the problem is. I (aswell as and many others) would love to help you on from there.

Vba email generator, subject from excel spreadsheet

I have a vba code that generates an email. I would like the subject to be the data from the first and last cells in my list. The thing is, my list isnt of a set length, sometimes it contains 5 pieces of data sometimes 8 etc. How do i tell vba to pick the first and last cell no matter the length of the list?
thanks
For me, best practice is to just have cells on your sheet that calculate the first and last row (different ways you can do that), then give those cells a range name such as FirstRow and LastRow. In your vba then you refer to these cells to make your code dynamic.
e.g:
firstRow = Range("FirstRow)
lastRow = Range("lastRow")
test = range(cells(firstRow,lastRow))
-- Note I have not written VBA in many many years so am writing the above from memory so it may be not be exact.
Of course you can do it all entirely in VBA using the xlDown method mentioned previously but I prefer the transparency of it being on the main page so that easily spot if something breaks.
Range("A1").End(xlDown).Value
Where the cell is where you want to start and the End part moves all the way to the end

VBA - Possibility of saying that SheetChange in specific Range is "something like True"?

First, I must admit that I am completely newbie here and in VBA mostly too. Thank you for this forum! :)
I have program that reacts on SheetChange to save the data. However, if there is formula added by macro, it doesn't cause the SheetChange. Copying and inserting as values isn't possible - there are 7k rows and the program acts on every SheetChange (colors and other stuff) - the time is not bearable.
Is there any possibility to have EnableEvents = False (to turn of getting SheetChange), then specify the Range of the changed cells (always rather the whole column - there are 2 columns only that interest me) and then let the program save data. The coloring of the cells and so on would remain (this coloring and so on has to stay in the program)
Is it even possible that it would work? If it could, how should I tell the macro that specific Range has SheetChange?
Apologies if the question is totally stupid.
Thank you very much for reading at least.
In the sheet change event, just specify that it should only save when Target is within the specified range. For the formulas, use the Calculate event and repeat essentially the same code.
So, if you only want it to save when the changed cell is in the first column and only within a certain row range (for example), add If Target.Column = 1 And Target.Row > 5 And Target.Row <= 10 Then to your change event.
For the Formula issue, add the following routine
Private Sub Worksheet_Calculate()
'your code here
End Sub

Find/replace conditionally formatted cells

I've been using a conditional format formula =OR(B2=B1,B2=B3) to highlight consecutive duplicates. I then use format painter to copy the formula to all columns in my excel table.
I have set up a button that will, amongst other things, copy a workbook into a new workbook. I now want to include the above formula in this macro. My final objective is to replace all of the cells found with this formula with an asterisk (*).
I first tried to just pop the formula into the macro as a starting point -
For Each sh In Destwb.Worksheets
With sh.UsedRange.FormatConditions _
.Add(Type:=xlExpression, Formula1:="=OR(B2=B1,B2=B3)")
.Interior.Color = RGB(198, 239, 206)
End With
Next sh
But this just makes a mess of seemingly randomly highlighted cells. I'm not sure where I've gone wrong. Even column B highlights are all wrong. Could the header in B1 affect this? It doesn't when I use the CF normally. How can I expand the CF into all columns uniquely?
Finally, how do I go about working a replacement of formatted cells into this formula? Or is there a quicker/easier way to meet this end-goal?
I didn't realise I could add custom text in that way. That's moved me a good couple of steps forward.
Taking Balinti's suggestion into consideration I've tried a workaround. I was making a couple of assumptions that turned out to be wrong. I have been able to enter the CF into the Array of data that I have in my original workbook. It's not as simple as putting it into a table, but by manually selecting the range in each column and inputting the CF I have made it work.
I also wasn't sure if the formatting would carry through to the new worksheet as I have used the Paste Special command to convert the array formula to values in the new sheet. It does, however, carry the formatting across which is very handy.
It's not the perfect solution for me but it appears to be working so far. I still need to test what happens when I change the date and get updated data. It would still be interesting to know if I can move this formatting into my macro though. Any tips?

Blank Fields Copied as #N/A

I am working with an Excel 2003 VBA script that copies the content from worksheets in an external Excel file to worksheets in our own:
ThisWorkbook.Sheets(strTarget).UsedRange.Value = Workbooks(strFile).Sheets(strSource).UsedRange.Value
In a large number of blank cells, this function is posting #N/A instead of the blank values, which causes errors further down in the VBA code. This only occurs on some sheets, while others copy over just fine, sometimes by adding these values in extra rows and other times in extra columns. I have attempted to clear the error with IsNA to no avail:
If (IsNA(Workbooks(strFile).Sheets(strSource).UsedRange.Value)) Then
ThisWorkbook.Sheets(strTarget).UsedRange.Value = ""
Else: ThisWorkbook.Sheets(strTarget).UsedRange.Value = Workbooks(strFile).Sheets(strSource).UsedRange.Value
Is there a simple way to remove these #N/A values during the copy or even clear them after the fact?
Any other advise on how to handle this issue would also be greatly appreicated, as I'm not a VBA dev myself, but simply the lucky soul who got to pick this up when the only person with Excel and VBA experience left our team. Thanks in advance!
The problem comes when the ranges aren't the same size. You should resize appropriately:
With Workbooks(strFile).Sheets(strSource).UsedRange
ThisWorkbook.Sheets(strTarget).UsedRange.Resize(.Rows.count, .Columns.count).Value = .Value
End With
It's probably safer to clear the target sheet first using:
ThisWorkbook.Sheets(strTarget).UsedRange.ClearContents