I'm sure someone will ask "Who cares?" but having been (badly?) influenced by a former colleague early in my career ("Never ever repeat the same calculation, just store the result and reuse it!") I'm updating an Excel spreadsheet which currently displays the weekday for days in the current year, using
=IF(AU2=0,DATE(YEAR(TODAY()),MONTH(A2),DAY(A2)),"")
where column A, rows 2-367 ("n" in the above formula), contain dates from 2016-01-01 to 2016-12-31, displayed as "1 January" to "31 December"
Column AW contains the above formula to display the weekdays, in (obviously) the current year where the value in column AU is zero.
To make the results a bit more dynamic, i.e. to display the weekday of the next year (potentially conditionally formatted in another colour) if year(today()) + the month and day of column A are before today, I can change the formula in column AW to
=IF(AU2=0,IF(DATE(YEAR(TODAY()),MONTH(A2),DAY(A2))<TODAY(),DATE(YEAR(TODAY())+1,MONTH(A2),DAY(A2)),DATE(YEAR(TODAY()),MONTH(A2),DAY(A2))),"")
(and to the same to the formulas in columns AX/AY/AZ, which display the weekdays if
AX: AU <> 0 & AU <= 250
AY: AU <> 0 & 250 < AU <= 500
AZ: UU <> 0 & 500 < AU <= 1000
but that results in the same long-winded calculation of the date being repeated 1,464 times, and this particular sheet is already quite slow, as it contains data for 39 years.
So, is there an (easy) way to simplify this kind of processing, like adding a (hidden) column containing the calculated date, or a thisyear/nextyear indicator to speed things up? Or do I just accept the "Who cares!" attitude?
In the worksheet, select the formula you want to make it reusable, and then click the New Autotext button. 3. In the New AutoText dialog box, type a name for this auto text entry in Name box, select Formulas in Group drop-down list, and then click the Add button.
see https://www.extendoffice.com/documents/excel/2634-excel-reuse-formula.html#:~:text=In%20the%20worksheet%2C%20select%20the,then%20click%20the%20Add%20button. for more information
Related
Cell G7 should show the time in HH : MM : SS until the US stock market is next open.
Cell G4 calculates either OPEN or CLOSED depending on if the VLOOKUP that searches the sheet ALGORITHM for either FALSE of TRUE for if each day the market is open (weekends are marked as FALSE as are any holidays) AND if the current time (found within cell B10)falls within market hours which are displayed at K6 and M6.
Current formulas:
G7 : =IF(G4="OPEN",M6-B10,K6-B10)
G4 : =IF(AND(VLOOKUP(B4,ALGORITHM!D5:ALGORITHM!J369,5,),B10>=K$6,B10<M$6),"OPEN","CLOSED")
Could anyone suggest a potential formula or VBA solution for this?
Life is easier when you are only trying to match on one condition. The way you have structured the problem, your HOME lookup formula has to look at a time from the current sheet, and the date from the algorithm sheet. This makes each comparison complicated. It's easier when you can look in ONE cell or ONE range, and test ONE condition, to get a result. Sometimes, doing this involves creating a "helper column." The problem being there are use cases where helper columns aren't possible. But in your case the algorithm sheet is "non-aesthetic" and can support helper columns.
So, add two "helper" columns to the Algorithm table, so your table looks like this:
1
A
B
C
D
E
(My Notes)
2
Date
Market Open
Remarks
untilOpen
untilClose
3
9/24/2022
FALSE
-
-
-
Blank because Past
4
9/25/2022
FALSE
-
-
-
Blank because Past
5
9/26/2022
TRUE
-
-
-
Blank because Past
6
9/27/2022
TRUE
-
-
-
Blank because Past
7
9/28/2022
TRUE
-
-
-
Blank because Past
8
9/29/2022
TRUE
-
0.44085
0.71168
Next Opening/closing
9
9/30/2022
TRUE
-
1.44085
1.71168
10
10/1/2022
FALSE
-
-
-
11
10/2/2022
FALSE
-
-
-
12
10/3/2022
TRUE
-
4.44085
4.71168
13
10/4/2022
TRUE
-
5.44085
5.71168
14
10/5/2022
TRUE
-
6.44085
6.71168
15
10/6/2022
TRUE
-
7.44085
7.71168
16
10/7/2022
TRUE
-
8.44085
8.71168
17
10/8/2022
FALSE
-
-
-
18
10/9/2022
FALSE
-
-
-
19
10/10/2022
FALSE
Holiday
-
-
Blank because holiday
20
10/11/2022
TRUE
-
12.44085
12.71168
21
10/12/2022
TRUE
-
13.44085
13.71168
My column D is the date/time stamp of how soon until the next open. E is how soon until the next close. These are dynamic and update based on NOW each time the sheet recalculates. (In Excel the integer portion is days and the decimal portion is partial days, that can still be formatted "d hh:mm:ss".) I leave it to you to play with the Excel formats to get the appearance you want.
My table's time stamps are based on the night of 9/28, and I also threw in a fake holiday on 10/10/22 for illustration.
Here's the formulas for those cells, which would then be copied down each column to all rows:
B2 I changed to a simpler formula than yours to determine weekday/holiday (and copied it down):
=AND(WEEKDAY(A2,2)<=5,C2="-")
B2 is TRUE if it's Mon through Fri and remarks is "-".
D2
=LET( open, A2 + TIME(9,30,0) - NOW(), IF( AND( B2, open > 0), open, "-"))
This says make the variable "open" = this row's date plus 9:30am minus NOW, which means this is an excel timestamp of time until that row's opening time.
If this time is still in the future, AND this is an open day, then place this timestamp in the cell, otherwise make it "=".
E2
=LET( close, A2 + TIME(16,0,0) - NOW(), IF( AND( B2, close > 0), close, "-"))
Does the same, but for this row's closing time.
See what I did? The bulk of the logic is in the algorithm table. Because I blank the timestamp for days past and holidays, my lookup is literally this simple:
The days/hours/minutes/seconds to the next opening is simply =MIN(D2:D21)
The same for the next closing, which is =MIN(E2:E21)
The ONLY remaining logic is for your home page to determine if the market is currently open or closed.
In fact, the next opening/closing event from "now" is simply =MIN(D2:E21) because the opening time will go blank in each row the moment the opening time passes. In other words the hours and minutes on your HOME page can always just come from =MIN(D2:E21) and all you have to to is determine if the current state is closed.
We've now removed all the complexity from the lookup. It's important to decide where you want to place the logic, in a complex lookup is often not the best place. We moved the logic to the schedule table.
BTW, some recommendations about your example:
In Excel, it's highly, highly recommended to avoid the use of merged cells. Your use of merged cells adds no additional aesthetic or usability. Merged cells decrease the intuitiveness of your logic and formulas, can complicate formatting, etc. Only use merged cells when there's a specific benefit to merged cells that can't be accomplished another way. You can just set row heights and column widths for better results.
Your data is not normalized for lookup and calculation. If the market opens and closes the same on any weekday that it's open, then just have a Mon - Fri row with 9:30 and 4:00pm in it. If you want the ability to support different hours each weekday, then have 10 cells (5 rows by 2 columns) with the open and close times, and then have the algorithm table do a lookup. You've created an aesthetic appearance of some day-of-week logic going on, and yet it catches the experienced person's eye that there actually isn't, and the time table is "just for show."
I have copied (copy/paste) a part of a home-page into an empty excel. One of the fields looks like this: 3140:01:00. If I check the format, it shows that the category is custom, and that the type is [t]:mm:ss. The problem is that I am only interested in the first 4 digits shown plus digits 6 and 7. If I change the format to e.g. text, I end up with a number. Probably a number, that identifies a specific date. In fact the first 4 digits are the length of a horse race! :-) I'm new at VB, but I have managed to clean up the rest of the information - but not this. Probably a known problem. Please help!
You will need to understand the difference between the value and the representation of your data (note that this is not VBA but Excel related). When you enter 3140:01:00 in a cell in Excel, Excel tries to understand what you enter. With the colon, it looks somehow like a time value, so Excel guesses that this a a time, convert what you enter into a date value (a date in Excel has automatically a time part) and put a number format that displays this date+time as [h]:mm:ss.
As I said, internally, what you entered is converted into a Date. Now a Date in Excel in internally stored as a number. If you set the number format to "Number", the cell will display 130.83402. This is because 3140 hours = 130 days + 20 hours. The 20 hours (plus the 1 minute) are stored as a fraction of a day (0.83402).
If you format the same value as Date/Time, you will see (depending on your regional settings) something like 05/09/1900 20:01:00 - because that is the 130th day in the Excel calendar (day 1 in Excel is 1/1/1900). Note that the value of the cell doesn't change, only the way it is displayed.
If you could prevent Excel to convert your input into a date, the solution would be to do string-handling, eg use the Split-function. When you format a cell as Text and enter 3140:01:00 manually, Excel leaves the string untouched and this would work. However, it seems that when you Paste the value into the cell, the number format is set automatically and the value is converted into a date even if the cell was formatted as Text before. I don't know if there is a way to tell Excel to not convert the data if it is pasted.
So what we can do instead is to convert the date value back into "hours", "minutes" and "seconds" - even if the "hours" are in fact something else (meters? yards? horse length?), and the minutes are probably also not minutes but whatever.
Several ways to do so.
If you don't mind that the strange pseudo-date value remains in your Excel (you can hide the column with that value), use just 2 simple formulas. Assuming your "date" is in D2:
use the formula =TRUNC(24*D2) to get the horse race length (the first number). We cannot use the Hour-formula here as this would return only 20 and not 3140.
use the formula =MINUTE(D2) to get the second number
use the formula =SECOND(D2) to get the third number
If you want to involve VBA:
Sub SplitStrangeDate(cell As Range)
If Not IsDate(cell) Then Exit Sub
Dim d As Date
d = cell.Value
Dim v1 As Long, v2 As Long, v3 As Long
v1 = CLng(d * 24)
v2 = Minute(d)
v3 = Second(d)
Debug.Print v1, v2, v3
End Sub
My aim with this is to create stock price alert(like Pop up message)/Because excel sheet contains more than 300 stock list
i don't want to scroll down excel sheet every time to check if refreshed price falls into any of these categories..
I have 8 columns in excel which consists of following information-
Column A-Stock Name
Column B-current stock price data which refreshes in every 5-10 seconds...
Column C-Ticker name
Next columns(D,E,F,G,H) i set them with manually entered prices for corresponding stocks for alert purpose.
If Refreshed price in column B falls in range 99% or 101% of columns values in D,E,F,G or H
i want to display a pop up message with Stock name with that cell address of corresponding cell in column D,E,F,G,or H ...
For Ex. If D2,E2,F2,G2 or H2 contains value 104.50 which is static and if B2 cell update its price dynamically to 105 then, B2 value falls in range 99% of D2(103.95) and 101% of D2(106.05) of D2..Once this Condition satisfies i want a popup alert...Any kind of help to simplify this task is most appreciated...
Check please the latest update of file:
https://drive.google.com/file/d/1itIZl3kMFR9f2Tf3ObB0qUprfp2rLm4r/view?usp=sharing
I added a scheduler, another sub iterates for each cell in B column every 5 seconds
I changed msgbox into debug.print to prevent crash excel.
You can find output messages in Immediate window:
Added:
Blockquote
We need a script to compare the dates in column D to the dates in column E.
If the date in column D is two days before the date in column E then we need column F to state that in the corresponding row to D. We have a range of 2 days before and 2 days after (shoulder days). We need to be able to easily reproduce this and have it be able to run when we import it into access. we have roughly 3300 unique days to check.
I have tried using datevalue or a formula but we need to be able to reproduce this in the future and the formula doesn't allow us to easily do that.
I will not provide a complete implementation, but I can show you the way how you can do it (either the Excel formula way or with VBA code). Both ways will automatically calculate the values you need so you can easily import it into Microsoft Access - the import will take the calculated values from the cells you've selected.
The first way, which is also the simplest way, is to do that with simple Excel formula, consider this picture showing how the formula will calculate the values in columns F and G:
(Note: It is showing German date format, but you can easily change that in Excel).
In column G it calculates the difference D2 - D1 and displays it in days.
Then, in column F there is a simple if condition to determine if the date D1 is less, greater or equal than D2. The Result is calculated automatically.
The formula in row 2 are:
Hint: You can drag and drop the formula to the rows 3 - n below, so you can create a lot of rows prefilled with that formula.
A second way is that you can write a VBA function for the (simple) calculation formula in column F:
Function CalcResult(D1 As Variant, D2 As Variant) As Variant
CalcResult = ""
Dim result As String
Dim diff As Single
diff = D2 - D1
If (diff > 0) Then
result = "D1 < D2"
ElseIf (diff = 0) Then
result = "D1 = D2"
ElseIf (diff < 0) Then
result = "D1 > D2"
End If
CalcResult = result
End Function
This needs to be entered in the VBA editor, which you can display if you press Alt+F11. After you have done that, press Alt+F11 again to close VBA and return to your Excel sheet.
Then, place the formula =CalcResult(E2; D2) in cell F2 as shown below:
Like in the previous example, you can drag & drop the formula to the rows 3 - n below, so you can create a lot of rows prefilled with that formula.
The advantage of the 2nd approach is that you can refine the function CalcResult later without having to change the cells again (as it is the case in the first example).
Note: The function above needs to be in a separate module and you need to save the workbook as "Macro enabled workbook" later - otherwise you'll lose the VBA code.
A third way is to use the Excel macro recorder and record whatever you intend to do. It will create a public module with VBA code. If the recorder asks you, choose to store the code in the workbook.
Later you re-visit the generated VBA code and refine it - for example, put a for loop around it to automate things you've recorded once.
This approach is good for creating a "Calculate" button and put some logic behind it.
I have months in my column header and I want Excel to Fill them in sequentially. It currently does this by default but it is filling in the long month even though it understands my short month.
Eg: I manually wrote in 'Sep' for September but it fills 'October' in the next column instead of 'Oct.'
I know Excel has both versions of months stored in it's default Custom Lists. How do I get it to switch?
You can use this formula :
=Text(A1,"mmm")
Where A1 is the cell/column/row, thus u can change it to your requirements.
After typing that formula drag it along the following rows and it will apply the formula accordingly.
Also for further refrence and/or questions u may also check this.
You can use this Formula in VBA to fill the rest of the months:
[A1] = "May"
[B1:L1].Formula = "=TEXT((A1 & "" 1"") + 50, ""mmm"")"
[B1:L1] = [B1:L1].Value2 ' optional to convert the formulas to values