Pause VBA from running until Excel calculated the sheet a second time - excel

A B C D E
1 Selection: DE
2 Value 1 200 =IF($B$1="DE",100,200)
3 Value 2 100 =IF($B$1="DE",300,800)
4
5
In the above Excel Sheet I can enter a country in Cell B1.
Based on the country the values in Range("B2:B3") switch accordingly as you can see in the IF formulas.
I copy the values of one country into Range("C2:C3") and another country into Range("D2:D3").
I use the below VBA to switch the country in Cell B1 and copy the values:
Sub Paste_Values()
Sheet1.Range("B1").Value = "DE"
Sheet1.Range("B2:B3").Copy
Sheet1.Range("C2:C3").PasteSpecial Paste:=xlPasteValues
Sheet1.Range("B1").Value = "US"
Sheet1.Range("B2:B3").Copy
Sheet1.Range("D2:D3").PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End Sub
In the simple example all this works perfectly.
Now, I have the issue that I want to apply the same logic in a much bigger file.
In this file I get the issue that somehow Excel calculates the IF formulas in Range("B2:B3") two times.
The first time it calculates #NA appears in the cells.
The second time it displays the correct numbers.
However, the VBA does not wait until Excel calculates it a second time.
Therefore, instead of the numbers it copies #NA in Range("C2:C3") and Range("D2:D3").
Is there a way to somehow let the VBA wait until the numbers are displayed in Range("B2:B3") so it is ensured that there is no #NA and the correct numbers are copied?

Related

combine all cells, numbers and symbols to a sum

Good day,
I'm at a loss on this problem.
I have a group of cells that contain words, like apple, this word would be the value. It is separated by a symbol for completing the math. They can be changed by the user to make custom calculations.
Cell A1 is "apple", B1 is "+", cell C1 is "apple", cell D1 is "*", cell E1 is "apple", call F1 is "=" and cell G1 is the suggested total, in this case would be "6".
It would be posted as | apple | + | apple | * | apple | = | 6 |
The legend holds the value for the word, so if you enter 2 in the legend, apple would be 2.
The logic would determine that the formula would be 2+2*2= if written in excel, I would like to combine all the cells and calculate this.
I tried using =sum, sumproduct, concate and the like to no avail.
Any head way I did make, I ended up getting BEDMAS wrong as it calculated it as 2+2=4*2=8, instead of the correct 2*2=4+2=6.
Anyone know of a way to combine these cells and properly sum the values to the correct total?
Thank you for your time!
Go to the Name manager and create named range Eval, into Refers to field add formula:
=EVALUATE(CONCATENATE(VLOOKUP(Sheet1!A1,Sheet1!$A$3:$B$5,2,0),Sheet1!B1,VLOOKUP(Sheet1!C1,Sheet1!$A$3:$B$5,2,0),Sheet1!D1,VLOOKUP(Sheet1!E1,Sheet1!$A$3:$B$5,2,0)))
In range A3:B5 I have legend.
Change references as you need. Then in cell G1 write formula =Eval.
Sample:
This is a UDF based solution. Its advantage is that it's more versatile and by far easier to maintain if you learn its elements of code. The disadvantage is in that you do have to learn the elements of code and you have an xlsm macro-enabled workbook which isn't welcome everywhere.
The setup is simple. I created a table with columns Item and Value. I placed it on another sheet than the task. In fact, you could make the sheet with the table VeryHidden so that the user can't look at it without access to the VBA project, which you can password protect. I called the table Legend. The item columns has names like apple, pear, orange. The Value column has the numeric values associated with each name.
Note that, since this is a VBA project, the entire list can be transferred to VBA leaving no trace on the sheet. You could have a function to display the value of each item as the user clicks on it and have it disappear as he clicks elsewhere.
Next I created a data validation drop-down in A1 with the List defined as =INDIRECT("Legend[Item]"). Copy this cell to C1 and E1.
Then I created another Data Validation drop-down in B1 with the list as +,-,*,/. This drop-down must be copied to D1.
Now the code below goes into a standard code module. Find the way to create it because it isn't any of those Excel sets up automatically. It's default name would be Module1. Paste the code there.
Function Evalue(Definition As Range) As Double
Dim Task As String
Dim Fact(2) As Double
Dim C As Long
Dim i As Long
With Definition
For C = 1 To 5 Step 2
On Error Resume Next
Fact(i) = Application.VLookup(.Cells(C).Value, Range("Legend"), 2, False)
i = i + 1
Next C
Task = "(" & Fact(0) & .Cells(2).Value _
& Fact(1) & ")" & .Cells(4).Value _
& Fact(2)
End With
Evalue = Evaluate(Task)
End Function
Now you are ready for testing. Call the function from the worksheet with a call like
=Evalue(A1:E1). You can use it in comparisons like =IF(G6 = Evalue(A1:E1), "Baravo!", "Try again"). As you change any of the components the cell with the function will change.
Remember to use absolute addressing if you copy formulas containing the range. If you need to get a result in VBA while testing, use this sub to call the function.
Private Sub TestEvalue()
Debug.Print Evalue(Range("A1:E1"))
End Sub
My Sheet
Here is what I have.
In cells M - U, i count all the instances of the word from cells E, G and I from the legend.
=SUMPRODUCT((LEN(E3)-LEN(SUBSTITUTE(E3,$B$3,"")))/LEN($B$3))
In cells W - AE, I multiply the instances with the value to give me a total each time the word appears.
=SUM(M3*$C$3)
In cell E8 - I8, i add the three possible values together.
=SUM(W3:Y3) so each worded cell is now a number.
I'd like to take the cells E8 - I8 to make a calculation in k8 and so on.
So, each cell is put together to make an
=SUM(E8:I8)
statement, which all works except E11 - I11 which equates to 26 instead of 43.

Macro is not reading the correct value from a cell which contains a math formula

I have a Excel Workbook that is a template and is populated using macros.
In a several cells, I have a formula =abs(sum(H20:P20)).
In my macro, I am trying to hide the row based on the value in that cell.
I reference those cells from a named range using an offset that does not change and then iterate over 8 lines to decide whether to hide them or not.
I have tried various 'Evaluate' and 'Calculate' functions on the cells in question thinking that maybe it was not evaluating the formula in the cell.
For s = 1 To 8
If Worksheets(sheet1).Range("Spend").Offset(s, 15).Value = 0 Then
Worksheets(sheet1).Range("Spend").Offset(s, 15).EntireRow.Hidden = True
End If
Next s
I expect it to hide several of the rows but it does not do anything. After all macros are done in the file; and the rows have not been hidden, I run that same macro again. On this second run, it hides the rows correctly.

How to clear a cell based on hours old, Excel VBA

I am trying to clear the contents of a cell within Microsoft Excel 2016 on one sheet when its age is over 8 hours. We review all incoming work after 8 hours and allocate additional resources if required.
I have 3 sheets Test, VLOOKUP and Log. Test is the only one visible to the general user, VLOOKUP holds the Vlookup tables to work out age, Log is exactly that, a log of all changes made.
Through the use of a a circular equation I have been able to output the time when a cell is altered, this is put into the VLOOKUP sheet -
=IF(Test!E6<>"",IF(K4="",NOW(),K4),"")
Within the VLOOKUP sheet, I have a cell that shows NOW (H3).
I want to be able to use the data from the VLOOKUP, K column, to feed the clear contents of the Test E:G columns, 1 row at a time and only if the K cell is over 8 hours old.
I have tried a number of options but, have not been able to clear another sheet based on VLOOKUP sheet values.
This is my current working -
Sub DeleteRowsBeforeCutoff()
Application.ScreenUpdating = False
If Worksheets("VLOOKUP").Range(K3) < DateAdd("h", -8, Now) Then
Worksheets("Test").Range(E5).ClearContents
End If
Application.ScreenUpdating = True
End Sub
Thanks in advance for any pointers!

Getting Percentage value to show in the correct format

I have two worksheets with data from different sources. I need to copy the data to a single worksheet and remove duplicates. To achieve this objective, I need all the data formatted the same on both worksheets. All of this is already coded except with one column of data I am having issues. These columns contain a representation for percentage. In worksheet A, the value is showing as .4386 which equates to 43.86%. I use this code that converts the value without issue:
Worksheets("Verification").Range("F2:F2000").NumberFormat = "0.00%"
In worksheet B, the same data is shown as 43.86, but the above code changes it to 4386.00%. I also tried changing this line to .NumberFormat = "General\%" and this almost works, but returns a value of 44%. What do I need to add to my code to get this to show 43.86% on worksheet B?
Sorry for the slow reply in comments - I will just submit an answer.
Like Ralph said, it's really better to make sure they are the same number.
43.1 and .431 are not the same number.
For Each c In [A1:A10]
If c.Value < 1 Then
c.Value = c.Value * 100
End If
c.NumberFormat = "0.00\%"
Next c
Results:
You are stating that .4386 on worksheet A is the same data [...] as 43.86 on worksheet B. So, Excel is correct to convert 43.86 to 4386.00%. Maybe you need a conditional formatting: when the number is smaller or equal to 1 then format it "0.00%" and otherwise format it as "0.00""%""".
Yet, I would assume that you'll be running into problems when comparing the data between the sheets with this solution. Hence, I would divide all numbers on sheet B by a 100 first to really make them comparable.
Note, that just by making numbers "look alike" they are not the same. Example: write in cell A1 the value 1000 and in cell B1 also 1000. Then change the number format for A1 to 0 and the number format for B1 to 0, (or to 0. outside the US). A1 will show 1000 while B1 will show 1. If you ask in cell C1 =A1=B1 you will get a TRUE as the answer.

Excel spreadsheet

I need a way of displaying 3 cells of data.
For example
Cell 1 Cell 2 Cell 3
20 140 Lee
12 110 Kerrie
Whenever anyone's name is input in cell 3 I need a separate spreadsheet to display the name (cell 3) and the information in cells 1 & 2 (the information in cells 1 & 2 will always be different).
From your question it's unclear whether you're talking about a person's name input into a single cell (e.g., "C3") or somewhere in a given column (e.g., "C:C").
In the former case you can easily use Guiness's suggestion; or you can even more easily write a formula like this to concatenate the values in Cells 1 through 3 (supposing the worksheet is called "Sheet1"):
="Name = "&Sheet1!C3&": Cell1 = "&Sheet1!A3&", Cell2 = "&Sheet1!B3
(This is based on Cells 1 through 3 in your example being in columns A through C, and in row 3.)
On the other hand, if you're talking about the latter case and you want to run some VBA code whenever a new name is ADDED to column C, you can use the Worksheet_Change VBA function. If this is the case, edit the question to indicate that.
Say you have Excel workbook 1 called Book1.xls. Open that workbook and type the following in the first three rows and across first three columns
Row 1 - cell1 cell2 cell3
Row 2 - 20 12 Jee
Row 3 - 87 25 Kee
Now open the other Workbook - say Book2.xls. Select the cell in which you want to put the value. In that cell press "=" (the 'equals' sign)
Now this is the important bit. After pressing that 'equals' go back to the first excel workbook and select the cell, the content of which you want entered in the second workbook.
So, in this case, the cell in the second workbook will have a formula like this
=[Book1]Sheet1!$A$2
Do the same for the rest of the cells you want.
Important: Please note that the second workbook will not be filled unless the first workbook is opened also.
Use the function: VLOOKUP

Resources